package cqrtplm.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.Expression;
import com.hustcad.plm.basic.constant.ObjectTypeConstant;
import com.hustcad.plm.basic.log.LogEventEnum;
import com.hustcad.plm.basic.util.TyplmLoggerUtil;
import com.hustcad.plm.basicdataimport.dto.StdTypeDetailDTO;
import com.hustcad.plm.pdm.audit.util.TyplmAuditLogUtil;
import com.hustcad.plm.pdm.common.model.vo.BusinessObjectVO;
import com.hustcad.plm.pdm.common.model.vo.iteration.CommonIteratorVO;
import com.hustcad.plm.pdm.flowbusiness.model.entity.FlowChangeIssueView;
import com.hustcad.plm.pdm.flowbusiness.model.entity.FlowChangeRequestView;
import com.hustcad.plm.pdm.flowbusiness.model.entity.FlowChgFormView;
import com.hustcad.plm.pdm.flowbusiness.model.entity.FlowObject;
import com.hustcad.plm.pdm.flowbusiness.model.entity.WorkFlowObjectPackage;
import com.hustcad.plm.pdm.flowbusiness.service.TyplmWorkFlowObjectPackageService;
import com.hustcad.plm.pdm.form.model.vo.TyplmFormDataVO;
import com.hustcad.plm.pdm.form.service.TyFormDataExtService;
import com.hustcad.plm.pdm.iba.model.dto.SaveObjIBADTO;
import com.hustcad.plm.pdm.iba.service.TyplmAttributeValueService;
import com.hustcad.plm.pdm.iteration.service.TyplmIterationService;
import com.hustcad.plm.pdm.lifestage.model.dto.EntityLifeCycleDTO;
import com.hustcad.plm.pdm.lifestage.service.TyplmLifecycleStageService;
import com.hustcad.plm.pdm.lifestage.service.TyplmLifecycleTemplateService;
import com.hustcad.plm.pdm.lifestage.service.impl.TyplmLifecycleStageServiceImpl;
import com.hustcad.plm.pdm.partbom.service.TyplmPartDescribeLinkService;
import com.hustcad.plm.pdm.partbom.service.TyplmPartRelObjectService;
import com.hustcad.plm.pdm.partbom.service.TyplmPartService;
import com.hustcad.plm.pdm.partbom.vo.PartDescribeDocVO;
import com.hustcad.plm.pdm.partbom.vo.QueryDescribeObjVO;
import com.hustcad.plm.pdm.partbom.vo.TyPartAllVO;
import com.hustcad.plm.pdm.partbom.vo.usagecount.PartUsageCountVO;
import com.hustcad.plm.pdm.redislock.TyplmRedisLockService;
import com.hustcad.plm.pdm.user.model.dto.OrgExtParamDTO;
import com.hustcad.plm.pdm.user.model.dto.PdmUserDTO;
import com.hustcad.plm.pdm.user.model.vo.OrgExtVO;
import com.hustcad.plm.pdm.user.service.TyOrgExtService;
import com.hustcad.plm.pdm.user.service.TyplmOrgService;
import com.hustcad.plm.pdm.user.service.TyplmPrincipalService;
import com.hustcad.plm.pdm.user.service.TyplmUserService;
import com.hustcad.plm.pdm.user.service.organization.PdmUserService;
import com.hustcad.plm.pdm.workflow.config.ContainerInstanceFactory;
import com.hustcad.plm.pdm.workflow.model.constant.WorkFlowErrorCodeEnum;
import com.hustcad.plm.pdm.workflow.model.entity.*;
import com.hustcad.plm.pdm.workflow.service.*;
import com.hustcad.plm.pdm.workflow.service.extend.TyplmWorkFlowContainerViewExtendService;
import com.hustcad.plm.pdm.workflow.service.impl.TyplmWorkFlowContainerInstanceDefaultServiceImpl;
import com.ty.basic.constant.TableTypeConstrant;
import com.ty.basic.dto.constraint.IbaDTO;
import com.ty.basic.entity.CTyEntityBaseDO;
import com.ty.basic.entity.IdentifierEntity;
import com.ty.basic.entity.PrincipalEntity;
import com.ty.basic.entity.cad.CADDocDO;
import com.ty.basic.entity.org.OrgDO;
import com.ty.basic.entity.org.UserDO;
import com.ty.basic.entity.part.PartDO;
import com.ty.basic.entity.part.PartDescribeLinkDO;
import com.ty.basic.exception.message.SystemErrorCodeEnum;
import com.ty.basic.session.TyAccountContext;
import com.ty.basic.utils.ArgumentUtils;
import com.ty.basic.vo.AttributeVO;
import cqrtplm.common.CommonService;
import cqrtplm.constant.RTErrorCodeEnum;
import cqrtplm.entity.DeptRoleDO;
import cqrtplm.entity.FlowTaskClaimDO;
import cqrtplm.mapper.DeptRoleMapper;
import cqrtplm.mapper.FlowTaskClaimMapper;
import cqrtplm.mapper.ProjectMapper;
import cqrtplm.mapper.RTPartMapper;
import cqrtplm.mapper.RTProjectCodeMapper;
import cqrtplm.service.FlowControlService;
import cqrtplm.service.RtOaFormMappingService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.delegate.DelegateExecution;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.util.UriComponentsBuilder;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigInteger;
import java.util.*;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author pieStar
 * @Date 2025/7/2 18:09
 */

@Service
@Slf4j
public class FlowControlServiceImpl implements FlowControlService {
    @Value("${ipd.base.url:http://127.0.0.1:9588}")
    private String ipdUrl;

    @Resource
    private TyplmWorkFlowContainerService typlmWorkFlowContainerService;
    @Resource
    private TyplmAttributeValueService typlmAttributeValueService;
    @Resource
    private FlowTaskClaimMapper flowTaskClaimMapper;
    @Resource
    private TyplmWorkFlowService typlmWorkFlowService;
    @Resource
    private TyplmUserService typlmUserService;
    @Resource
    private TyplmFlowTaskUserService typlmFlowTaskUserService;
    @Resource
    private TyplmPrincipalService typlmPrincipalService;
    @Resource
    private TyplmOrgService typlmOrgService;
    @Resource
    private DeptRoleMapper deptRoleMapper;
    @Resource
    private TyplmWorkFlowObjectPackageService typlmWorkFlowObjectPackageService;
    @Resource
    private TyplmWorkFlowProcessService typlmWorkFlowProcessService;
    @Resource
    private FlowControlService flowControlService;
    @Resource
    private TyplmWorkFlowContainerViewExtendService typlmWorkFlowContainerViewExtendService;
    @Resource
    private CommonService commonService;
    @Resource
    private TyOrgExtService tyOrgExtService;
    @Resource
    private TyplmWorkFlowtOperateTaskService typlmWorkFlowtOperateTaskService;
    @Resource
    private TyFormDataExtService tyFormDataExtService;
    @Resource
    private RTPartMapper rtPartMapper;
    @Resource
    private TyplmPartService typlmPartService;
    @Resource
    private RtOaFormMappingService rtOaFormMappingService;
    @Resource
    private TyplmRedisLockService typlmRedisLockService;
    @Resource
    private RTProjectCodeMapper projectCodeMapper;
    @Resource
    private TyplmIterationService typlmIterationService;
    @Resource
    private TyplmLifecycleTemplateService typlmLifecycleTemplateService;
    @Resource
    private TyplmPartRelObjectService typlmPartRelObjectService;
    @Resource
    private TyplmPartDescribeLinkService typlmPartDescribeLinkService;


    @Override
    public void parallelNodeCheckListener(BigInteger workFlowContainerId, String nodeId) {
        WorkFlowContainerView workFlowContainerView = typlmWorkFlowContainerService.getWorkFlowContainerDetailByPrimaryKey(
                workFlowContainerId);
        List<FlowTaskRecord> flowTaskRecordList = workFlowContainerView.getFlowTaskRecordList();
        List<UserTaskDTO> userTaskList = workFlowContainerView.getUserTaskList();
        List<String> nodeIds = ListUtil.toList(nodeId.split(","));
        List<UserTaskDTO> userTaskDTOList = userTaskList.stream().filter(
                userTaskDTO -> nodeIds.contains(userTaskDTO.getId())).collect(Collectors.toList());
        if (CollUtil.isEmpty(userTaskDTOList)) {
            return;
        }
        Map<String, UserTaskDTO> userTaskDTOMap = userTaskDTOList.stream().collect(
                Collectors.toMap(UserTaskDTO::getId, Function.identity(), (k1, k2) -> k1));


        for (FlowTaskRecord flowTaskRecord : flowTaskRecordList) {
            if (userTaskDTOMap.containsKey(flowTaskRecord.getTaskDefId())) {
                String operateName = flowTaskRecord.getOperateName();
                if ("通过".equals(operateName) || "批准".equals(operateName) || "同意".equals(operateName)) {
                    userTaskDTOMap.remove(flowTaskRecord.getTaskDefId());
                }
            }
        }

        if (CollUtil.isNotEmpty(userTaskDTOMap)) {
            String names = userTaskDTOMap.values().stream().map(UserTaskDTO::getName).collect(Collectors.joining(","));

            throw RTErrorCodeEnum.WORK_FLOW_EXECUTE_EXCEPTION.getException(
                    "当前节点不可提交，需要等待[" + names + "]提交后，才可提交");
        }
    }


    @Override
    public void chooseFLowBranch(BigInteger workFlowContainerId, String expressionText, DelegateExecution execution) {
        WorkFlowContainerView workFlowContainerView = typlmWorkFlowContainerService.getWorkFlowContainerDetailByPrimaryKey(
                workFlowContainerId);
        String formData = getFromDataByWorkFlowContainer(workFlowContainerView);
        JSONObject formDataJson = JSONObject.parseObject(formData);
        JSONArray array = JSONArray.parseArray(expressionText);
        String value = null;
        try {
            for (Object o : array) {
                JSONObject json = (JSONObject) o;
                String expressionTemplate = json.getString("exp");
                String exp = "(${a}>10&&${a}<100) || (${b}>10&&${b}<100)";
                Map<String, Object> env = extractVariables(expressionTemplate, formDataJson);

                try {
                    expressionTemplate = removeElSyntax(expressionTemplate);
                    Expression compiledExp = AviatorEvaluator.compile(expressionTemplate, true);
                    Boolean result = (Boolean) compiledExp.execute(env);
                    if (Boolean.TRUE.equals(result)) {
                        log.info("满足条件: {}", expressionTemplate);
                        value = json.getString("value");
                        log.info("====flag====>: {}", value);
                        return;
                    } else {
                        log.info("不满足条件: {}", expressionTemplate);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("表达式执行失败: {}", expressionTemplate, e);
                }
            }
        } finally {
            execution.setVariable("param", value);
        }
    }

    private String getFromDataByWorkFlowContainer(WorkFlowContainerView workFlowContainerView) {
        String formData = "";
        if ((workFlowContainerView instanceof WorkFlowObjectPackage)) {
            log.info("当前流程属于普通流程");
            WorkFlowObjectPackage workFlowObjectPackage = (WorkFlowObjectPackage) workFlowContainerView;
            List<FlowObject> flowObjectList = workFlowObjectPackage.getFlowObjectList();
            String refObjectOtype = flowObjectList.get(0).getRefObjectOtype();

            if (TableTypeConstrant.TY_FORMDATA_TYPE.equalsIgnoreCase(refObjectOtype)) {
                BigInteger refObjectOid = flowObjectList.get(0).getRefObjectOid();
                TyplmFormDataVO formDataVO = this.tyFormDataExtService.getFormDataDetail(refObjectOid);
                formData = formDataVO.getFormdata().toJSONString();
            }

        } else if (workFlowContainerView instanceof FlowChgFormView) {
            log.info("当前流程属于变更流程/发布流程");
            FlowChgFormView flowChgFormView = (FlowChgFormView) workFlowContainerView;
            formData = flowChgFormView.getChgFormVO().getFormData();

        } else if (workFlowContainerView instanceof FlowChangeRequestView) {
            log.info("当前流程属于变更请求流程");
            FlowChangeRequestView flowChangeRequestView = (FlowChangeRequestView) workFlowContainerView;
            formData = flowChangeRequestView.getChgRequestDetailVO().getFormData();
        } else if (workFlowContainerView instanceof FlowChangeIssueView) {
            log.info("当前流程属于变更问题流程");
            FlowChangeIssueView flowChangeIssueView = (FlowChangeIssueView) workFlowContainerView;
            formData = flowChangeIssueView.getChangeIssueDTO().getFormData();
        } else {

        }
        return formData;
    }


    /**
     * 去除表达式中的 ${}，转换为 Aviator 可识别的格式
     *
     * @param expression 原始表达式，如：(${ProjectNo}>10&&${ProjectNo}<100)
     * @return 标准 Aviator 表达式，如：(ProjectNo>10&&ProjectNo<100)
     */
    public String removeElSyntax(String expression) {
        if (expression == null || expression.isEmpty()) {
            return expression;
        }

        Pattern pattern = Pattern.compile("\\$\\{([^}]*)}");
        Matcher matcher = pattern.matcher(expression);

        StringBuffer sb = new StringBuffer();
        int lastEnd = 0;

        while (matcher.find()) {
            // 添加非匹配部分
            sb.append(expression, lastEnd, matcher.start());
            // 添加提取的变量名
            sb.append(matcher.group(1));
            lastEnd = matcher.end();
        }

        // 添加最后剩余部分
        sb.append(expression.substring(lastEnd));

        return sb.toString();
    }

    /**
     * 提取变量名
     *
     * @param expr
     * @return
     */
    public Map<String, Object> extractVariables(String expr, JSONObject formDataJson) {
        Set<String> vars = new HashSet<>();
        Pattern pattern = Pattern.compile("\\$\\{(.*?)\\}");
        Matcher matcher = pattern.matcher(expr);
        while (matcher.find()) {
            vars.add(matcher.group(1));
        }
        Map<String, Object> env = new HashMap<>();
        for (String var : vars) {
            String value = getParamFormData(formDataJson, var);

            if (StringUtils.isNotBlank(value)) {
                try {
                    // 转成数字以便比较
                    env.put(var, Double.parseDouble(value));
                } catch (NumberFormatException e) {
                    env.put(var, value); // 非数值保留字符串
                }
            } else {
                env.put(var, null); // 缺失字段处理
            }
        }
        return env;
    }

    /**
     * 从表单数据中提取指定变量的值
     *
     * @param formDataJson 表单数据JSON对象
     * @param var 要查找的变量名
     * @return 找到的变量值，未找到则返回空字符串
     */
    private String getParamFormData(JSONObject formDataJson, String var) {
        for (Map.Entry<String, Object> entry : formDataJson.entrySet()) {
            Object value = entry.getValue();
            if (value instanceof String) {
                // 如果键匹配，则返回对应的值
                if (var.equals(entry.getKey())) {
                    return String.valueOf(value);
                }
            } else if (value instanceof JSONArray) {
                // 如果是数组，递归遍历每个元素
                JSONArray jsonArray = (JSONArray) value;
                for (int i = 0; i < jsonArray.size(); i++) {
                    Object item = jsonArray.get(i);
                    if (item instanceof JSONObject) {
                        String result = getParamFormData((JSONObject) item, var);
                        if (StringUtils.isNotBlank(result)) {
                            return result;
                        }
                    }
                }
            } else if (value instanceof JSONObject) {
                // 如果是对象，递归查找
                String result = getParamFormData((JSONObject) value, var);
                if (StringUtils.isNotBlank(result)) {
                    return result;
                }
            }
        }
        return ""; // 未找到返回空字符串
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void transitionStage(String workFlowContainerId, String stageValue) {

        // 根据工作流容器ID获取容器视图详情
        WorkFlowContainerView workFlowContainerView = typlmWorkFlowContainerService.getWorkFlowContainerDetailByPrimaryKey(
                new BigInteger(workFlowContainerId));

        // 检查容器是否为WorkFlowObjectPackage类型且不为空
        if (workFlowContainerView instanceof WorkFlowObjectPackage) {
            WorkFlowObjectPackage workFlowObjectPackage = (WorkFlowObjectPackage) workFlowContainerView;
            List<FlowObject> flowObjectList = workFlowObjectPackage.getFlowObjectList();

            if (CollUtil.isEmpty(flowObjectList)) {
                return;
            }
            // 只处理图纸类型的对象 过滤掉图样代号相关对象
            List<FlowObject> drawingObjects = flowObjectList.stream()
                    .filter(obj -> TableTypeConstrant.TY_CADDOC_OTYPE.equals(obj.getRefObjectOtype())
                            || TableTypeConstrant.TY_DOC_OTYPE.equals(obj.getRefObjectOtype()))
                    .collect(Collectors.toList());
            // 如果没有图纸类型的对象，直接返回
            if (CollUtil.isEmpty(drawingObjects)) {
                return;
            }

            List<SaveObjIBADTO> objWithIbaList = new ArrayList<>();
            List<CommonIteratorVO> cadCommonIteratorVOList = new ArrayList<>();
            List<CommonIteratorVO> docCommonIteratorVOList = new ArrayList<>();
            for (FlowObject flowObject : drawingObjects) {
                if (TableTypeConstrant.TY_DOC_OTYPE.equals(flowObject.getRefObjectOtype())) {
                    //更新DOC
                    CommonIteratorVO commonIteratorVO = getCommonIteratorVO(flowObject.getRefObjectOid(),
                                                                            flowObject.getRefObjectOtype());
                    docCommonIteratorVOList.add(commonIteratorVO);
                }

                if (TableTypeConstrant.TY_CADDOC_OTYPE.equals(flowObject.getRefObjectOtype())) {
                    //更新CAD
                    CommonIteratorVO commonIteratorVO = getCommonIteratorVO(flowObject.getRefObjectOid(),
                                                                            flowObject.getRefObjectOtype());
                    cadCommonIteratorVOList.add(commonIteratorVO);
                }

            }
            log.info("a>>>>>>>>>>>>>>>>>{}", objWithIbaList);
            if (CollUtil.isNotEmpty(docCommonIteratorVOList)) {
                updateAndPreviousVersionStatus(docCommonIteratorVOList, stageValue);
            }
            if (CollUtil.isNotEmpty(cadCommonIteratorVOList)) {
                majorVersionUpdate(cadCommonIteratorVOList, stageValue);
            }

        }
    }

    /**
     * @param oid
     * @param type
     * @return EntityLifeCycleDTO
     * @author fxw
     * @description 获取实体生命周期DTO
     * @since 2025/11/20 09:51
     */
    @NotNull
    private EntityLifeCycleDTO getEntityLifeCycleDTO(BigInteger oid, String type) {
        EntityLifeCycleDTO entityLifeCycleDTO = new EntityLifeCycleDTO();
        entityLifeCycleDTO.setOid(oid);
        entityLifeCycleDTO.setOtype(type);
        entityLifeCycleDTO.setLifeCycleStageKey("RELEASED");
        return entityLifeCycleDTO;
    }

    /**
     * @param oid
     * @param type
     * @return CommonIteratorVO
     * @author fxw
     * @description 获取通用迭代器VO
     * @since 2025/11/20 09:59
     */
    @NotNull
    private CommonIteratorVO getCommonIteratorVO(BigInteger oid, String type) {
        CommonIteratorVO commonIteratorVO = new CommonIteratorVO();
        UserDO admin = typlmUserService.queryUserByName("admin");
        commonIteratorVO.setId(String.valueOf(oid));
        commonIteratorVO.setTypeDefName(type);
        commonIteratorVO.setUserID(String.valueOf(admin.getOid()));
        commonIteratorVO.setWorkSpaceId(null);
        commonIteratorVO.setCheckInMark("更新小版本");
        return commonIteratorVO;
    }

    private void transition(String stageValue, BigInteger oid, String oType, List<SaveObjIBADTO> saveObjIBADTOList) {
        SaveObjIBADTO saveObjIBADTO = new SaveObjIBADTO();
        List<IbaDTO> ibaDTOList = new ArrayList<>();
        // 处理业务版本
        IbaDTO ibaDTO1 = new IbaDTO();
        ibaDTO1.setKey("BusinessEdition");
        ibaDTO1.setValue(stageValue + "1");
        ibaDTOList.add(ibaDTO1);
        // 处理阶段
        IbaDTO ibaDTO2 = new IbaDTO();
        ibaDTO2.setKey("Stage");
        ibaDTO2.setValue(stageValue);
        ibaDTOList.add(ibaDTO2);
        saveObjIBADTO.setObjIbaList(ibaDTOList);
        saveObjIBADTO.setCTyEntityBaseDO(
                new CTyEntityBaseDO(oid, oType));
        saveObjIBADTOList.add(saveObjIBADTO);
    }


    /**
     * 根据当前阶段确定下一阶段和业务版本，并创建保存对象
     *
     * @param flowObject 流程对象
     * @param attributeVOS 当前属性值列表
     * @param objWithIbaList 用于保存的对象列表
     * @return 下一阶段值
     */
    private String getStageAndSaveObjDTO(FlowObject flowObject,
                                         List<AttributeVO> attributeVOS,
                                         List<SaveObjIBADTO> objWithIbaList) {
        // 创建IBA DTO列表
        List<IbaDTO> ibaDTOList = new ArrayList<>();
        String stage = "";

        // 处理业务版本
        IbaDTO ibaDTO1 = new IbaDTO();
        ibaDTO1.setKey("BusinessEdition");

        // 处理阶段
        IbaDTO ibaDTO2 = new IbaDTO();
        ibaDTO2.setKey("Stage");

        // 如果存在属性值
        if (CollUtil.isNotEmpty(attributeVOS)) {
            // 分别获取Stage和BusinessEdition的当前值
            String currentStage = "";
            String currentBusinessEdition = "";

            // 遍历属性值，分别获取阶段和业务版本的当前值
            for (AttributeVO attr : attributeVOS) {
                if ("Stage".equals(attr.getAttributeName())) {
                    currentStage = attr.getAttributeValue();
                } else if ("BusinessEdition".equals(attr.getAttributeName())) {
                    currentBusinessEdition = attr.getAttributeValue();
                }
            }

            // 根据当前阶段确定下一阶段和业务版本
            if ("S".equals(currentStage)) {
                ibaDTO2.setValue("A");
                stage = "A";
                ibaDTO1.setValue("A1");
            }
            // A阶段转B阶段时，业务版本设为B1
            else if ("A".equals(currentStage)) {
                ibaDTO2.setValue("B");
                stage = "B";
                ibaDTO1.setValue("B1");
            } else if ("B".equals(currentStage)) {
                throw RTErrorCodeEnum.DOC_TYPE_ERROR.getException("已经是B阶段不允许转换");
            }
        } else {
            // 初始状态：S阶段，业务版本S8
            ibaDTO2.setValue("S");
            stage = "S";
            ibaDTO1.setValue("S8");
        }

        ibaDTOList.add(ibaDTO1);
        ibaDTOList.add(ibaDTO2);
        // 创建保存对象并添加到列表中
        SaveObjIBADTO saveObjIBADTO = new SaveObjIBADTO();
        saveObjIBADTO.setObjIbaList(ibaDTOList);
        saveObjIBADTO.setCTyEntityBaseDO(
                new CTyEntityBaseDO(flowObject.getRefObjectOid(), flowObject.getRefObjectOtype()));
        objWithIbaList.add(saveObjIBADTO);

        return stage;
    }

    /**
     * @param
     * @return void
     * @author fxw
     * @description 更新版本和上版本状态
     * @since 2025/11/14 16:58
     */

    private void updateAndPreviousVersionStatus(List<CommonIteratorVO> commonIteratorVOList, String stageValue) {
        List<EntityLifeCycleDTO> entityLifeCycleDTOList = new ArrayList<>();
        List<SaveObjIBADTO> saveObjIBADTOS = new ArrayList<>();
        List<BusinessObjectVO> businessObjectVOS = typlmIterationService.batchCheckOut(commonIteratorVOList);
        commonIteratorVOList.clear();
        businessObjectVOS.forEach(businessObjectVO -> {
            entityLifeCycleDTOList.add(
                    getEntityLifeCycleDTO(businessObjectVO.getId(), businessObjectVO.getTypeDefName()));
            commonIteratorVOList.add(getCommonIteratorVO(businessObjectVO.getId(), businessObjectVO.getTypeDefName()));
            this.transition(stageValue, businessObjectVO.getId(), businessObjectVO.getTypeDefName(), saveObjIBADTOS);
        });
        UserDO user = this.typlmUserService.queryUserByName("admin");
        if (Objects.nonNull(user)) {
            TyAccountContext.setUser(user);
        }
        //更新新对象
        typlmIterationService.batchCheckIn(commonIteratorVOList);
        typlmAttributeValueService.batchSaveIBAByObjsNoConstraint(saveObjIBADTOS, false);
        typlmLifecycleTemplateService.batchUpdateEntityLifecycle(entityLifeCycleDTOList, true, false, false);
    }

    /**
     * @param
     * @return void
     * @author fxw
     * @description 更新大版本
     * @since 2025/11/14 16:58
     */
    private void majorVersionUpdate(List<CommonIteratorVO> commonIteratorVOList, String stageValue) {
        List<EntityLifeCycleDTO> entityLifeCycleDTOList = new ArrayList<>();
        List<SaveObjIBADTO> saveObjIBADTOS = new ArrayList<>();
        UserDO user = this.typlmUserService.queryUserByName("admin");
        if (Objects.nonNull(user)) {
            TyAccountContext.setUser(user);
        }
        //更新新对象
        List<BusinessObjectVO> businessObjectVOS = typlmIterationService.batchNewVersionWithPolicy(
                commonIteratorVOList);
        businessObjectVOS.forEach(businessObjectVO -> {
            entityLifeCycleDTOList.add(
                    getEntityLifeCycleDTO(businessObjectVO.getId(), businessObjectVO.getTypeDefName()));
            this.transition(stageValue, businessObjectVO.getId(), businessObjectVO.getTypeDefName(), saveObjIBADTOS);
        });
        //
        typlmAttributeValueService.batchSaveIBAByObjsNoConstraint(saveObjIBADTOS, false);
        typlmLifecycleTemplateService.batchUpdateEntityLifecycle(entityLifeCycleDTOList, true, false, false);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)

    public String processTaskClaim(String taskDefKey, String workFlowContainerId, String taskId, UserDO user) {
        String key = taskDefKey + ":" + workFlowContainerId;
        FlowTaskClaimDO taskClaimDO = flowTaskClaimMapper.selectByPrimaryKey(key);
        if (taskClaimDO != null) {
            String username = user.getFullname();
            String claimMsg = username + "已认领";
            taskClaimDO.setClaimMsg(claimMsg);
            FlowTaskClaimDO.fillCommonFieldForUpdate(taskClaimDO, new Date());
            flowTaskClaimMapper.updateByPrimaryKey(taskClaimDO);
            return claimMsg;
        }
        String username = user.getFullname();
        BigInteger userOid = user.getOid();
        log.info("用户{}认领任务{}", username, taskId);
        String claimMsg = username + "已认领";
        FlowTaskClaimDO flowTaskClaimDO = new FlowTaskClaimDO(key, taskId, taskDefKey, String.valueOf(userOid),
                                                              username, claimMsg);
        FlowTaskClaimDO.fillCommonFieldForCreate(flowTaskClaimDO, new Date());
        int insert = flowTaskClaimMapper.insert(flowTaskClaimDO);
        if (insert == 1) {
            return claimMsg;
        } else {
            throw RTErrorCodeEnum.OBJECTNUMBER_NOT_EXIST.getException("任务认领失败");
        }
    }

    @Override
    public FlowTaskClaimDO selectClaimMsgByTaskId(String taskId) {
        return flowTaskClaimMapper.selectByPrimaryKey(taskId);
    }

    @Override
    public WorkFlow getDefaultWorkFlow(String templateName) {
        Example example = new Example(WorkFlow.class, true, true);
        example.createCriteria().andEqualTo("name", templateName);
        List<WorkFlow> workFlowList = this.typlmWorkFlowService.simpleQueryListByExample(example);
        if (ObjectUtils.isEmpty(workFlowList)) {
            throw RTErrorCodeEnum.NOT_FOUND_OBJECT_WORK_FLOW_TEMPLATE.getException();
        }
        return workFlowList.get(0);
    }

    @Override
    public List<PdmUserDTO> getPdmUserDTOS(List<String> userNameList) {
        List<UserDO> userDOList = typlmUserService.queryUserByNameList(userNameList);
        if (CollUtil.isNotEmpty(userDOList)) {
            List<PdmUserDTO> userList = new ArrayList<>();
            if (CollUtil.isEmpty(userDOList)) {
                return userList;
            }
            for (UserDO userDO : userDOList) {
                PdmUserDTO pdmUserDTO = new PdmUserDTO();
                BeanUtils.copyProperties(userDO, pdmUserDTO);
                pdmUserDTO.setOid(userDO.getOid().toString());
                pdmUserDTO.setOtype(userDO.getOtype());
                pdmUserDTO.setAccount(userDO.getName());
                pdmUserDTO.setUsername(userDO.getFullname());
                userList.add(pdmUserDTO);
            }
            return userList;
        } else {
            throw RTErrorCodeEnum.USER_NOT_FOUND.getException(userNameList);
        }
    }

    @Override
    public void chooseFLowBranch2(BigInteger workFlowContainerId, String condition, String nodes) {
        WorkFlowContainerView workFlowContainerView = typlmWorkFlowContainerService.getWorkFlowContainerDetailByPrimaryKey(
                workFlowContainerId);
        String formData = getFromDataByWorkFlowContainer(workFlowContainerView);
        JSONObject formDataJson = JSONObject.parseObject(formData);
        JSONArray conditionArray = JSONArray.parseArray(condition);
        JSONObject conditionJson = conditionArray.getJSONObject(0);
        String expressionTemplate = conditionJson.getString("exp");
        Map<String, Object> env = extractVariables(expressionTemplate, formDataJson);

        try {
            expressionTemplate = removeElSyntax(expressionTemplate);
            Expression compiledExp = AviatorEvaluator.compile(expressionTemplate, true);
            Boolean result = (Boolean) compiledExp.execute(env);
            //            JSONObject jsonObject = formDataJson.getJSONObject("testObj");
            //            String bargain = jsonObject.getString("@Bargain#");
            if (result) {
                List<UserTaskDTO> userTaskList = workFlowContainerView.getUserTaskList();
                Map<String, UserTaskDTO> userTaskMap = userTaskList.stream().collect(
                        Collectors.toMap(UserTaskDTO::getId, item -> item));
                String[] split = nodes.split(",");
                for (String node : split) {
                    if (userTaskMap.containsKey(node)) {
                        UserTaskDTO userTaskDTO = userTaskMap.get(node);
                        userTaskDTO.getUserList().clear();
                    }
                }
            }
            this.typlmFlowTaskUserService.updateUserTaskList(workFlowContainerView);
        } catch (Exception e) {
            e.printStackTrace();
            //            log.error("表达式执行失败: {}", expressionTemplate, e);
        }
    }

    @Override
    public void checkInitiatorDepartmentBranch(BigInteger workFlowContainerId, String nodeId,
                                               String departmentCondition) {
        WorkFlowContainerView workFlowContainerView = typlmWorkFlowContainerService.getWorkFlowContainerDetailByPrimaryKey(
                workFlowContainerId);

        try {
            // 第一步：获取发起者信息
            UserDO initiator = TyAccountContext.getUser();
            if (initiator == null) {
                return;
            }

            // 第二步：获取发起者部门信息
            String initiatorDepartment = getInitiatorDepartmentName(initiator);
            if (StringUtils.isBlank(initiatorDepartment)) {
                return;
            }

            // 第三步：根据部门条件判断是否应该清空节点
            boolean shouldClearNode = !evaluateDepartmentCondition(initiatorDepartment, departmentCondition);

            if (shouldClearNode) {
                List<UserTaskDTO> userTaskList = workFlowContainerView.getUserTaskList();
                Map<String, UserTaskDTO> userTaskMap = userTaskList.stream()
                        .collect(Collectors.toMap(UserTaskDTO::getId, item -> item));

                if (userTaskMap.containsKey(nodeId)) {
                    UserTaskDTO userTaskDTO = userTaskMap.get(nodeId);
                    userTaskDTO.getUserList().clear();
                }
            }
            // 第四步：更新用户任务列表
            this.typlmFlowTaskUserService.updateUserTaskList(workFlowContainerView);

        } catch (Exception e) {
            log.error("发起者部门分支判断失败", e);
        }
    }


    /**
     * 获取发起者部门名称（包含子部门识别）
     */
    private String getInitiatorDepartmentName(UserDO initiator) {
        try {
            BigInteger oid = initiator.getOid();
            PrincipalEntity principalEntity = new PrincipalEntity(oid, TableTypeConstrant.TY_USER_OTYPE);
            List<PrincipalEntity> outParent = typlmPrincipalService.getOneOutParentOrg(principalEntity);
            typlmOrgService.dealOrgParentPath(outParent);
            if (CollUtil.isEmpty(outParent)) {
                return "";
            }
            for (PrincipalEntity entity : outParent) {
                if (entity instanceof OrgDO) {
                    OrgDO orgDO = (OrgDO) entity;
                    String containerotype = orgDO.getContainerotype();
                    if (TableTypeConstrant.TY_ORGCONTAINER_OTYPE.equals(containerotype)) {
                        return orgDO.getName();
                    }
                }
            }
            return "";
        } catch (Exception e) {
            log.error("获取发起者部门信息失败", e);
            return "";
        }
    }

    /**
     * 获取发起者部门及其所有子部门名称列表
     *
     * @param initiator 发起者用户
     * @return 部门名称列表（包含主部门和所有子部门）
     */
    private List<String> getInitiatorDepartmentNamesWithChildren(UserDO initiator) {
        List<String> departmentNames = new ArrayList<>();
        try {
            // 1. 获取发起者的直接部门
            String mainDepartment = getInitiatorDepartmentName(initiator);
            if (StringUtils.isNotBlank(mainDepartment)) {
                departmentNames.add(mainDepartment);

                // 2. 通过TyOrgExtService获取子部门
                try {
                    // 获取部门OID
                    BigInteger departmentOid = getDepartmentOidByName(mainDepartment);
                    if (departmentOid != null) {
                        // 调用TyOrgExtService获取子部门
                        OrgExtParamDTO paramDTO = new OrgExtParamDTO();
                        paramDTO.setOid(departmentOid);

                        // 使用TyOrgExtService获取成员组织（包括子部门）
                        List<OrgExtVO> memberOrgs = tyOrgExtService.getMemberOrgsByOrg(paramDTO);
                        if (CollUtil.isNotEmpty(memberOrgs)) {
                            for (OrgExtVO orgExtVO : memberOrgs) {
                                if (StringUtils.isNotBlank(orgExtVO.getName())) {
                                    departmentNames.add(orgExtVO.getName());
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    log.warn("获取子部门信息失败，仅使用主部门: {}", e.getMessage());
                }
            }
        } catch (Exception e) {
            log.error("获取发起者部门及子部门信息失败", e);
        }
        return departmentNames;
    }

    /**
     * 根据部门名称获取部门OID
     */
    private BigInteger getDepartmentOidByName(String departmentName) {
        try {
            // 通过部门名称查询部门信息
            OrgDO orgDO = typlmOrgService.getOrgByName(departmentName);
            return orgDO != null ? orgDO.getOid() : null;
        } catch (Exception e) {
            log.error("根据部门名称获取OID失败: {}", departmentName, e);
            return null;
        }
    }

    /**
     * 评估部门条件表达式（自动包含子部门匹配）
     * 支持复杂表达式，包括 OR、AND、==、!= 等操作符
     * 示例：dept=='通机新能源研究院' or dept=='OPE研究院' and dept!='小轮产品开发所'
     * 注意：会自动匹配主部门及其所有子部门，无需在表达式中特殊标识
     * 运算符优先级：AND > OR
     * 返回值：true表示符合条件（不清空节点），false表示不符合条件（清空节点）
     */
    private boolean evaluateDepartmentCondition(String initiatorDepartment, String departmentCondition) {
        if (StringUtils.isBlank(initiatorDepartment) || StringUtils.isBlank(departmentCondition)) {
            return false;
        }

        try {
            // 处理 OR 操作符（优先级最低，最后处理）
            // 使用正则表达式分割，忽略引号内的 or
            String[] orParts = splitByOperatorOutsideQuotes(departmentCondition, "OR");

            if (orParts.length > 1) {
                // OR 逻辑：只要有一个条件为 true，整个表达式就为 true
                for (String orPart : orParts) {
                    if (evaluateAndExpression(initiatorDepartment, orPart.trim())) {
                        log.debug("OR条件满足: {}", orPart.trim());
                        return true;
                    }
                }
                log.debug("所有OR条件都不满足");
                return false;
            } else {
                // 没有 OR，继续处理 AND
                return evaluateAndExpression(initiatorDepartment, departmentCondition);
            }
        } catch (Exception e) {
            log.error("评估部门条件失败: {}", departmentCondition, e);
            return false;
        }
    }

    /**
     * 评估部门条件表达式（自动包含子部门匹配）
     *
     * @param initiator 发起者用户
     * @param departmentCondition 部门条件表达式
     * @return true表示符合条件（不清空节点），false表示不符合条件（清空节点）
     */
    private boolean evaluateDepartmentConditionWithChildren(UserDO initiator, String departmentCondition) {
        if (initiator == null || StringUtils.isBlank(departmentCondition)) {
            return false;
        }

        try {
            // 获取发起者部门及其所有子部门
            List<String> departmentNames = getInitiatorDepartmentNamesWithChildren(initiator);
            if (CollUtil.isEmpty(departmentNames)) {
                return false;
            }

            // 处理 OR 操作符（优先级最低，最后处理）
            String[] orParts = splitByOperatorOutsideQuotes(departmentCondition, "OR");

            if (orParts.length > 1) {
                // OR 逻辑：只要有一个条件为 true，整个表达式就为 true
                for (String orPart : orParts) {
                    if (evaluateAndExpressionWithChildren(departmentNames, orPart.trim())) {
                        log.debug("OR条件满足: {}", orPart.trim());
                        return true;
                    }
                }
                log.debug("所有OR条件都不满足");
                return false;
            } else {
                // 没有 OR，继续处理 AND
                return evaluateAndExpressionWithChildren(departmentNames, departmentCondition);
            }
        } catch (Exception e) {
            log.error("评估部门条件失败: {}", departmentCondition, e);
            return false;
        }
    }

    /**
     * 评估 AND 表达式
     */
    private boolean evaluateAndExpression(String initiatorDepartment, String expression) {
        // 处理 AND 操作符（优先级高于 OR）
        String[] andParts = splitByOperatorOutsideQuotes(expression, "AND");

        if (andParts.length > 1) {
            // AND 逻辑：所有条件都必须为 true，整个表达式才为 true
            for (String andPart : andParts) {
                if (!evaluateSingleCondition(initiatorDepartment, andPart.trim())) {
                    log.debug("AND条件不满足: {}", andPart.trim());
                    return true;
                }
            }
            log.debug("所有AND条件都满足");
            return false;
        } else {
            // 没有 AND，直接评估单个条件
            return evaluateSingleCondition(initiatorDepartment, expression);
        }
    }

    /**
     * 评估 AND 表达式（自动包含子部门匹配）
     */
    private boolean evaluateAndExpressionWithChildren(List<String> departmentNames, String expression) {
        // 处理 AND 操作符（优先级高于 OR）
        String[] andParts = splitByOperatorOutsideQuotes(expression, "AND");

        if (andParts.length > 1) {
            // AND 逻辑：所有条件都必须为 true，整个表达式才为 true
            for (String andPart : andParts) {
                if (!evaluateSingleConditionWithChildren(departmentNames, andPart.trim())) {
                    log.debug("AND条件不满足: {}", andPart.trim());
                    return true;
                }
            }
            log.debug("所有AND条件都满足");
            return false;
        } else {
            // 没有 AND，直接评估单个条件
            return evaluateSingleConditionWithChildren(departmentNames, expression);
        }
    }

    /**
     * 评估单个条件（自动包含子部门匹配）
     *
     * @param departmentNames 部门名称列表（包含主部门和子部门）
     * @param condition 单个条件表达式
     * @return true表示条件满足
     */
    private boolean evaluateSingleConditionWithChildren(List<String> departmentNames, String condition) {
        if (CollUtil.isEmpty(departmentNames) || StringUtils.isBlank(condition)) {
            return false;
        }

        try {
            // 解析条件表达式
            condition = condition.trim();

            // 处理 == 操作符
            if (condition.contains("==")) {
                String[] parts = condition.split("==", 2);
                if (parts.length == 2) {
                    String left = parts[0].trim();
                    String right = parts[1].trim();

                    if ("dept".equals(left)) {
                        // 去掉引号
                        right = right.replaceAll("^['\"]|['\"]$", "");

                        // 在部门列表中查找匹配（自动包含子部门）
                        for (String deptName : departmentNames) {
                            // 精确匹配主部门名称
                            if (deptName.equals(right)) {
                                log.debug("部门精确匹配成功: {}", deptName);
                                return true;
                            }
                            // 子部门匹配：检查子部门是否包含指定部门名称
                            if (deptName.contains(right) && !deptName.equals(right)) {
                                log.debug("子部门匹配成功: {} 包含 {}", deptName, right);
                                return true;
                            }
                        }
                        return false;
                    }
                }
            }

            // 处理 != 操作符
            if (condition.contains("!=")) {
                String[] parts = condition.split("!=", 2);
                if (parts.length == 2) {
                    String left = parts[0].trim();
                    String right = parts[1].trim();

                    if ("dept".equals(left)) {
                        // 去掉引号
                        right = right.replaceAll("^['\"]|['\"]$", "");

                        // 在部门列表中查找匹配，如果找到则不满足条件（自动包含子部门）
                        for (String deptName : departmentNames) {
                            // 精确匹配主部门名称
                            if (deptName.equals(right)) {
                                log.debug("部门精确匹配失败（!=条件）: {}", deptName);
                                return false;
                            }
                            // 子部门匹配：检查子部门是否包含指定部门名称
                            if (deptName.contains(right) && !deptName.equals(right)) {
                                log.debug("子部门匹配失败（!=条件）: {} 包含 {}", deptName, right);
                                return false;
                            }
                        }
                        return true; // 没有找到匹配的部门，满足 != 条件
                    }
                }
            }

            log.warn("无法解析条件表达式: {}", condition);
            return false;
        } catch (Exception e) {
            log.error("评估单个条件失败: {}", condition, e);
            return false;
        }
    }

    /**
     * 按操作符分割表达式（忽略引号内的操作符）
     *
     * @param expression 表达式
     * @param operator 操作符（OR 或 AND）
     * @return 分割后的字符串数组
     */
    private String[] splitByOperatorOutsideQuotes(String expression, String operator) {
        List<String> parts = new ArrayList<>();
        StringBuilder currentPart = new StringBuilder();
        boolean inQuotes = false;
        char quoteChar = ' ';

        int i = 0;
        while (i < expression.length()) {
            char c = expression.charAt(i);

            // 处理引号
            if ((c == '\'' || c == '"') && (i == 0 || expression.charAt(i - 1) != '\\')) {
                if (!inQuotes) {
                    inQuotes = true;
                    quoteChar = c;
                } else if (c == quoteChar) {
                    inQuotes = false;
                }
                currentPart.append(c);
                i++;
                continue;
            }

            // 如果不在引号内，检查是否匹配操作符
            if (!inQuotes) {
                boolean matched = false;
                // 检查当前位置是否匹配操作符（忽略大小写）
                if (i + operator.length() <= expression.length()) {
                    String substring = expression.substring(i, i + operator.length());
                    if (substring.equalsIgnoreCase(operator)) {
                        // 确保操作符前后是空格或边界
                        boolean validBefore = (i == 0 || !Character.isLetterOrDigit(expression.charAt(i - 1)));
                        boolean validAfter = (i + operator.length() >= expression.length() ||
                                !Character.isLetterOrDigit(expression.charAt(i + operator.length())));

                        if (validBefore && validAfter) {
                            parts.add(currentPart.toString());
                            currentPart = new StringBuilder();
                            i += operator.length();
                            matched = true;
                        }
                    }
                }

                if (!matched) {
                    currentPart.append(c);
                    i++;
                }
            } else {
                currentPart.append(c);
                i++;
            }
        }

        // 添加最后一部分
        if (currentPart.length() > 0) {
            parts.add(currentPart.toString());
        }

        // 如果没有找到操作符，返回原表达式
        return parts.isEmpty() ? new String[]{expression} : parts.toArray(new String[0]);
    }

    /**
     * 发起者角色分支判断
     * 根据发起者角色判断流程分支，清空不匹配分支的执行人
     *
     * @param workFlowContainerId 工作流容器ID
     * @param nodeId 节点ID
     * @param roleCondition 角色条件表达式，如：role != '部门主管' 或 role == '部门主管'
     */
    @Override
    public void checkInitiatorRoleBranch(BigInteger workFlowContainerId, String nodeId, String roleCondition) {
        WorkFlowContainerView workFlowContainerView = typlmWorkFlowContainerService.getWorkFlowContainerDetailByPrimaryKey(
                workFlowContainerId);

        try {
            // 第一步：获取发起者信息
            UserDO initiator = TyAccountContext.getUser();
            if (initiator == null) {
                log.warn("无法获取发起者信息，跳过角色分支判断");
                return;
            }

            // 第二步：获取发起者部门信息
            String initiatorDepartment = getInitiatorDepartmentName(initiator);
            if (StringUtils.isBlank(initiatorDepartment)) {
                log.warn("无法获取发起者部门信息，跳过角色分支判断");
                return;
            }

            // 第三步：判断发起者是否是部门主管
            boolean isDepartmentManager = isInitiatorDepartmentManager(initiator);

            log.info("发起者角色分支判断 - 发起者：{}，部门：{}，是否部门主管：{}，条件：{}",
                     initiator.getName(), initiatorDepartment, isDepartmentManager, roleCondition);

            // 第四步：根据角色条件判断是否应该清空节点
            boolean shouldClearNode = !evaluateRoleCondition(isDepartmentManager, roleCondition);

            if (shouldClearNode) {
                // 清空节点执行人
                List<UserTaskDTO> userTaskList = workFlowContainerView.getUserTaskList();
                Map<String, UserTaskDTO> userTaskMap = userTaskList.stream()
                        .collect(Collectors.toMap(UserTaskDTO::getId, item -> item));

                if (userTaskMap.containsKey(nodeId)) {
                    UserTaskDTO userTaskDTO = userTaskMap.get(nodeId);
                    //userTaskDTO.getUserList().clear();
                    log.info("角色分支判断：清空节点 {} 的执行人", nodeId);
                }
            } else {
                log.info("角色分支判断：保留节点 {} 的执行人", nodeId);
            }

            // 第五步：更新用户任务列表
            //this.typlmFlowTaskUserService.updateUserTaskList(workFlowContainerView);

        } catch (Exception e) {
            log.error("发起者角色分支判断失败", e);
        }
    }

    /**
     * 判断发起者是否是部门主管
     *
     * @param initiator 发起者用户信息
     * @return true表示是部门主管，false表示不是部门主管
     */
    private boolean isInitiatorDepartmentManager(UserDO initiator) {
        try {
            BigInteger oid = initiator.getOid();
            PrincipalEntity principalEntity = new PrincipalEntity(oid, TableTypeConstrant.TY_USER_OTYPE);
            List<PrincipalEntity> outParent = typlmPrincipalService.getOneOutParentOrg(principalEntity);
            typlmOrgService.dealOrgParentPath(outParent);

            if (CollUtil.isEmpty(outParent)) {
                log.warn("无法获取发起者组织关系，默认不是部门主管");
                return false;
            }

            // 获取部门ID
            String deptId = "";
            for (PrincipalEntity entity : outParent) {
                if (entity instanceof OrgDO) {
                    OrgDO orgDO = (OrgDO) entity;
                    String containerotype = orgDO.getContainerotype();
                    if (TableTypeConstrant.TY_ORGCONTAINER_OTYPE.equals(containerotype)) {
                        deptId = String.valueOf(orgDO.getOid());
                        break;
                    }
                }
            }

            if (StringUtils.isBlank(deptId)) {
                log.warn("无法获取发起者部门ID，默认不是部门主管");
                return false;
            }

            // 根据部门ID查询该部门的所有角色配置信息
            List<DeptRoleDO> deptRoleDOS = deptRoleMapper.selectByDeptOid(deptId);
            if (CollUtil.isEmpty(deptRoleDOS)) {
                log.warn("部门 {} 没有配置角色信息，默认不是部门主管", deptId);
                return false;
            }

            // 查找发起者是否在部门主管角色中
            for (DeptRoleDO deptRoleDO : deptRoleDOS) {
                // 检查用户ID或用户编号是否匹配，且角色名称是"部门主管"
                if (("部门主管".equals(deptRoleDO.getRoleName())) &&
                        (String.valueOf(initiator.getOid()).equals(deptRoleDO.getUserId()) ||
                                initiator.getName().equals(deptRoleDO.getUserNo()))) {
                    log.info("发起者 {} 是部门主管", initiator.getName());
                    return true;
                }
            }

            log.info("发起者 {} 不是部门主管", initiator.getName());
            return false;
        } catch (Exception e) {
            log.error("判断发起者是否是部门主管失败", e);
            return false;
        }
    }

    /**
     * 评估角色条件表达式
     * 支持类似 role != '部门主管' 或 role == '部门主管' 的表达式
     *
     * @param isDepartmentManager 发起者是否是部门主管
     * @param roleCondition 角色条件表达式
     * @return true表示符合条件（不清空节点），false表示不符合条件（清空节点）
     */
    private boolean evaluateRoleCondition(boolean isDepartmentManager, String roleCondition) {
        if (StringUtils.isBlank(roleCondition)) {
            return false;
        }
        try {
            log.info("开始评估角色条件，发起者是否部门主管：{}，条件表达式：{}", isDepartmentManager, roleCondition);

            // 预处理表达式，去除多余空格
            String processedCondition = roleCondition.trim().replaceAll("\\s+", " ");

            // 评估表达式
            boolean result = evaluateRoleExpression(isDepartmentManager, processedCondition);

            log.info("角色条件评估结果：{}", result);
            return result;
        } catch (Exception e) {
            log.error("评估角色条件失败: {}", roleCondition, e);
            return false;
        }
    }

    /**
     * 评估角色表达式
     *
     * @param isDepartmentManager 发起者是否是部门主管
     * @param expression 表达式
     * @return 评估结果
     */
    private boolean evaluateRoleExpression(boolean isDepartmentManager, String expression) {
        // 处理相等条件：role == '部门主管'
        if (expression.contains("==")) {
            String[] parts = expression.split("==");
            if (parts.length == 2) {
                String leftSide = parts[0].trim();
                String rightSide = parts[1].trim().replace("'", "").replace("\"", "");

                if ("role".equals(leftSide)) {
                    if ("部门主管".equals(rightSide)) {
                        boolean result = isDepartmentManager;
                        log.debug("评估角色相等条件：发起者是否部门主管 == {}，结果：{}", rightSide, result);
                        return result;
                    }
                }
            }
        }
        // 处理不等条件：role != '部门主管'
        else if (expression.contains("!=")) {
            String[] parts = expression.split("!=");
            if (parts.length == 2) {
                String leftSide = parts[0].trim();
                String rightSide = parts[1].trim().replace("'", "").replace("\"", "");
                if ("role".equals(leftSide)) {
                    if ("部门主管".equals(rightSide)) {
                        boolean result = !isDepartmentManager;
                        log.debug("评估角色不等条件：发起者是否部门主管 != {}，结果：{}", rightSide, result);
                        return result;
                    }
                }
            }
        }

        log.warn("无法识别的角色条件表达式：{}", expression);
        return false;
    }

    /**
     * 评估单个条件
     * 支持 == 和 != 操作符（包括中文符号 ！=）
     */
    private boolean evaluateSingleCondition(String initiatorDepartment, String condition) {
        // 规范化条件表达式，将中文符号转换为英文符号
        condition = condition.replace("！", "!");

        // 先尝试 != 操作符（因为要先检查双字符操作符）
        if (condition.contains("!=")) {
            int operatorIndex = condition.indexOf("!=");
            String leftSide = condition.substring(0, operatorIndex).trim();
            String rightSide = condition.substring(operatorIndex + 2).trim();
            rightSide = removeQuotes(rightSide);

            if ("dept".equals(leftSide)) {
                boolean result = !initiatorDepartment.equals(rightSide);
                log.debug("评估条件 [{}] != [{}]，发起者部门: [{}]，结果: {}",
                          leftSide, rightSide, initiatorDepartment, result);
                return result;
            }
        }
        // 再尝试 == 操作符
        else if (condition.contains("==")) {
            int operatorIndex = condition.indexOf("==");
            String leftSide = condition.substring(0, operatorIndex).trim();
            String rightSide = condition.substring(operatorIndex + 2).trim();
            rightSide = removeQuotes(rightSide);

            if ("dept".equals(leftSide)) {
                boolean result = initiatorDepartment.equals(rightSide);
                log.debug("评估条件 [{}] == [{}]，发起者部门: [{}]，结果: {}",
                          leftSide, rightSide, initiatorDepartment, result);
                return result;
            }
        }

        log.warn("无法识别的部门条件表达式：{}", condition);
        return false;
    }

    /**
     * 移除字符串两端的引号（单引号或双引号）
     */
    private String removeQuotes(String str) {
        if (str == null) {
            return "";
        }
        str = str.trim();
        if ((str.startsWith("'") && str.endsWith("'")) ||
                (str.startsWith("\"") && str.endsWith("\""))) {
            return str.substring(1, str.length() - 1);
        }
        return str;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void startIpdWorkFlow(JSONObject params) {
        UserDO user = TyAccountContext.getUser();
        WorkFlow workFlow = flowControlService.getDefaultWorkFlow("解密流程");
        List<PdmUserDTO> userList = flowControlService.getPdmUserDTOS(Collections.singletonList(user.getFullname()));
        //设置第一个节点的参与者
        String url = ipdUrl + "/api/v1/project/getProjectByOID";
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url)
                .queryParam("projectOID", params.getBigInteger("projectOid"));
        JSONObject plan;
        try {
            String s = commonService.sendGetRequestToIPD(builder.toUriString());
            plan = JSONObject.parseObject(s).getJSONObject("data");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        if (plan == null) {
            return;
        }
        List<FlowObject> flowObjectList = dealFlowObjectList(plan);
        BigInteger containerOid = flowObjectList.get(0).getContainerOid();
        String containerOtype = flowObjectList.get(0).getContainerOtype();
        List<UserTaskDTO> allUserTask = typlmWorkFlowContainerService.getAllUserTask(workFlow.getOid(), containerOid,
                                                                                     containerOtype);
        WorkFlowObjectPackage containerView = getWorkFlowContainerView(allUserTask, workFlow, flowObjectList, userList,
                                                                       "解密流程");
        typlmWorkFlowObjectPackageService.insert(containerView);
        this.typlmWorkFlowProcessService.startProcess(containerView, true);
    }

    private List<FlowObject> dealFlowObjectList(JSONObject plan) {
        List<FlowObject> flowObjectList = new ArrayList<>();
        FlowObject flowObject = new FlowObject();
        flowObject.setRefObjectOid(plan.getBigInteger("oid"));
        flowObject.setRefObjectOtype(plan.getString("otype"));
        flowObject.setVersion(plan.getString("version"));
        flowObject.setRefObjectName(plan.getString("name"));
        flowObject.setContainerOid(plan.getBigInteger("oid"));
        flowObject.setContainerOtype(plan.getString("otype"));
        flowObjectList.add(flowObject);
        log.info("流程对象============>flowObjectList:{}", flowObjectList);
        return flowObjectList;
    }

    @Override
    public Boolean checkIsNeedClaim(String taskId) {
        boolean flag = false;
        FlowTaskInfo taskDetailView = this.typlmWorkFlowProcessService.getTaskDetailView(taskId);
        this.typlmWorkFlowtOperateTaskService.setFlowNodeInfo(taskDetailView, null, "flowTask");
        WorkFlowContainerView workFlowContainerView = taskDetailView.getWorkFlowContainerView();
        List<UserTaskDTO> userTaskList = workFlowContainerView.getUserTaskList();
        Map<String, UserTaskDTO> userTaskMap = userTaskList.stream().collect(
                Collectors.toMap(UserTaskDTO::getId, item -> item));
        String taskDefKey = taskDetailView.getTaskDefKey();
        if (userTaskMap.containsKey(taskDefKey)) {
            UserTaskDTO userTaskDTO = userTaskMap.get(taskDefKey);
            List<PdmUserDTO> userList = userTaskDTO.getUserList();
            if (userList.size() == 1) {
                flag = true;
            }
        }
        return flag;
    }

    @Override
    public void checkDepartmentSupervisor(BigInteger bigInteger, UserDO initiator, DelegateExecution execution) {
        // 第一步：获取发起者信息
        if (initiator == null) {
            log.warn("无法获取发起者信息，跳过角色分支判断");
            return;
        }
        // 第二步：获取发起者部门信息
        String initiatorDepartment = getInitiatorDepartmentName(initiator);
        if (StringUtils.isBlank(initiatorDepartment)) {
            log.warn("无法获取发起者部门信息，跳过角色分支判断");
            return;
        }
        List<String> arr = new ArrayList<>();

        boolean isDepartmentManager = isInitiatorDepartmentManager(initiator);
        if (isDepartmentManager) {
            execution.setVariable("SFBMZG", "true");
        } else {
            execution.setVariable("SFBMZG", "false");
        }

        OrgDO orgDO = typlmOrgService.queryOrgByNames(Collections.singletonList(initiatorDepartment)).get(0);
        callBack(orgDO, arr);
        execution.setVariable("FQZBM", arr.toString());
    }

    public void callBack(OrgDO orgDO, List arr) {
        if (orgDO == null) {
            return;
        }
        String orgName = orgDO.getName();
        arr.add(orgName);
        String id = deptRoleMapper.selectParentOrgId(orgDO.getOid());
        if (StringUtils.isNotBlank(id)) {
            OrgDO org = typlmOrgService.queryOrgById(new BigInteger(id));
            callBack(org, arr);
        }
    }

    @Override
    public void checkMixture(BigInteger workFlowContainerId, String nodeIdValue, String departmentCondition,
                             String nodeId,
                             String condition) {
        WorkFlowContainerView workFlowContainerView = typlmWorkFlowContainerService.getWorkFlowContainerDetailByPrimaryKey(
                workFlowContainerId);
        String formData = getFromDataByWorkFlowContainer(workFlowContainerView);
        JSONObject formDataJson = JSONObject.parseObject(formData);
        try {
            // 第一步：获取发起者信息
            UserDO initiator = TyAccountContext.getUser();
            if (initiator == null) {
                return;
            }
            // 第二步：获取发起者部门信息
            String initiatorDepartment = getInitiatorDepartmentName(initiator);
            if (StringUtils.isBlank(initiatorDepartment)) {
                return;
            }
            // 第三步：根据部门条件判断是否应该清空节点
            boolean shouldClearNode = !evaluateDepartmentCondition(initiatorDepartment, departmentCondition);
            JSONObject jsonObject = formDataJson.getJSONObject("testObj");
            String bargain = jsonObject.getString("@Bargain#");

            if (shouldClearNode && (!"是".equals(bargain))) {
                List<UserTaskDTO> userTaskList = workFlowContainerView.getUserTaskList();
                Map<String, UserTaskDTO> userTaskMap = userTaskList.stream()
                        .collect(Collectors.toMap(UserTaskDTO::getId, item -> item));

                if (userTaskMap.containsKey(nodeId)) {
                    UserTaskDTO userTaskDTO = userTaskMap.get(nodeId);
                    userTaskDTO.getUserList().clear();
                }
            }
            // 第四步：更新用户任务列表
            this.typlmFlowTaskUserService.updateUserTaskList(workFlowContainerView);

        } catch (Exception e) {
            log.error("发起者部门分支判断失败", e);
        }


    }

    @Override
    public void checkPartUsage(String workFlowContainerId) {
        // 根据工作流容器ID获取容器视图详情
        WorkFlowContainerView workFlowContainerView = typlmWorkFlowContainerService.getWorkFlowContainerDetailByPrimaryKey(
                new BigInteger(workFlowContainerId));
        // 检查容器是否为WorkFlowObjectPackage类型且不为空
        if (!Objects.isNull(workFlowContainerView) && workFlowContainerView instanceof WorkFlowObjectPackage) {
            WorkFlowObjectPackage workFlowObjectPackage = (WorkFlowObjectPackage) workFlowContainerView;
            List<FlowObject> flowObjectList = workFlowObjectPackage.getFlowObjectList();
            if (CollUtil.isEmpty(flowObjectList)) {
                return;
            }

            List<FlowObject> partObjects = flowObjectList.stream()
                    //.filter(item -> TableTypeConstrant.TY_PART_OTYPE.equals(item.getRefObjectOtype()))
                    .filter(item -> !"图样代号".equals(item.getType()))
                    .collect(Collectors.toList());

            List<FlowObject> patternCodeObjects = flowObjectList.stream()
                    .filter(item -> "图样代号".equals(item.getType()))
                    .collect(Collectors.toList());

            if (CollUtil.isEmpty(partObjects) && CollUtil.isEmpty(patternCodeObjects)) {
                return;
            }
            // 流程中所有物料
            List<String> partNumbers = flowObjectList.stream()
                    .map(FlowObject::getObjectNumber)
                    .collect(Collectors.toList());

            StringBuffer msg = new StringBuffer();
            StringBuffer msg2 = new StringBuffer();
            // 处理非图样代号
            for (FlowObject flowObject : partObjects) {
                if (usedByBom(flowObject.getRefObjectOid())) {
                    msg.append(flowObject.getObjectNumber()).append("、");
                }
            }

            // 处理图样代号
            for (FlowObject flowObject : patternCodeObjects) {
                String tydhNumber = flowObject.getObjectNumber();
                if (log.isDebugEnabled()) {
                    log.debug("处理图样代号===>{}", tydhNumber);
                }
                if (usedByBom(flowObject.getRefObjectOid())) {
                    msg.append(flowObject.getObjectNumber()).append("、");
                }
                String emsg = "";
                List<String> MaterialCodeList = rtPartMapper.querySimilarPartNumber(tydhNumber);
                for (String tempCode : MaterialCodeList) {
                    if (partNumbers.contains(tempCode)) {
                        continue;
                    }
                    if (log.isDebugEnabled()) {
                        log.debug("图样代号衍生的流程外的物料码MaterialCode===>{}", tempCode);
                    }
                    PartDO additionalPart = typlmPartService.queryPartByNumber(tempCode).get(0);
                    if (!additionalPart.getLifecyclestagekey().equals("DISABLED")) {
                        if (emsg.length() > 0) {
                            emsg += ",";
                        }
                        emsg += tempCode;

                    }
                }
                if (StringUtils.isNotBlank(emsg)) {
                    msg2.append(tydhNumber).append("关联的不在流程中的物料码").append(emsg).append("未失效。");
                }
            }
            if (StringUtils.isBlank(msg.toString())) {
                if (StringUtils.isNotBlank(msg2.toString())) {
                    throw RTErrorCodeEnum.DRAWING_CODE_NAME_ERROR.getException(msg2);
                }
            } else {
                throw RTErrorCodeEnum.DRAWING_CODE_NAME_ERROR.getException(
                        msg.substring(0, msg.length() - 1) + "被用于非失效的BOM结构中，当前流程不允许失效。" + msg2);
            }
        }
    }

    /**
     * 是否被有效的BOM使用
     *
     * @param oid
     * @return
     */
    private Boolean usedByBom(BigInteger oid) {
        Map<BigInteger, List<PartUsageCountVO>> partUsageLinkVOMap = commonService.queryPartUsageParent(
                Collections.singletonList(oid), "direct", "0");
        List<PartUsageCountVO> partUsageCountVOS = partUsageLinkVOMap.get(oid);
        if (CollUtil.isEmpty(partUsageCountVOS)) {
            return false;
        }
        for (PartUsageCountVO vo : partUsageCountVOS) {
            if (!"DISABLED".equalsIgnoreCase(vo.getLifecyclestagekey())) {
                return true;
            }
        }
        return false;
    }

    @Resource
    private PdmUserService pdmUserService;

    @Override
    public void addTaskByFormData(String workFlowContainerId, String typeStr) {
        WorkFlowContainerView workFlowContainerView = typlmWorkFlowContainerService
                .getWorkFlowContainerDetailByPrimaryKey(new BigInteger(workFlowContainerId));

        if (!isValidType(typeStr)) {
            return;
        }

        // 根据类型处理不同的业务逻辑
        if ("委托人".equals(typeStr)) {
            handleEntrustorTasks(workFlowContainerView);
        } else if ("开发处理人".equals(typeStr)) {
            handleDeveloperTasks(workFlowContainerView);
        }
    }

    /**
     * 验证类型是否有效
     */
    private boolean isValidType(String typeStr) {
        return "委托人".equals(typeStr) || "开发处理人".equals(typeStr);
    }

    /**
     * 处理委托人相关任务
     */
    private void handleEntrustorTasks(WorkFlowContainerView workFlowContainerView) {
        String formData = getFromDataByWorkFlowContainer(workFlowContainerView);
        JSONObject formDataJson = JSONObject.parseObject(formData);
        JSONObject jsonObject = formDataJson.getJSONObject("testObj");
        JSONArray jsonArray = jsonObject.getJSONArray("DelegatedDepartment");

        BigInteger userId = extractUserIdFromJsonArray(jsonArray);
        if (Objects.equals(userId, BigInteger.ZERO)) {
            return;
        }

        Map<String, String> roleMapping = createEntrustorRoleMapping();
        processUserTasks(workFlowContainerView, userId, roleMapping, true);
    }

    /**
     * 处理开发处理人相关任务
     */
    private void handleDeveloperTasks(WorkFlowContainerView workFlowContainerView) {
        BigInteger userId = extractDeveloperUserId(workFlowContainerView);
        if (Objects.equals(userId, BigInteger.ZERO)) {
            return;
        }

        Map<String, String> roleMapping = createDeveloperRoleMapping();
        processUserTasks(workFlowContainerView, userId, roleMapping, false);
    }

    /**
     * 从JSON数组中提取用户ID
     */
    private BigInteger extractUserIdFromJsonArray(JSONArray jsonArray) {
        if (CollUtil.isEmpty(jsonArray)) {
            return BigInteger.ZERO;
        }

        for (Object obj : jsonArray) {
            JSONObject userJson = (JSONObject) obj;
            BigInteger userId = userJson.getBigInteger("oid");
            if (userId != null && !Objects.equals(userId, BigInteger.ZERO)) {
                return userId;
            }
        }
        return BigInteger.ZERO;
    }

    /**
     * 从开发处理人任务中提取用户ID
     */
    private BigInteger extractDeveloperUserId(WorkFlowContainerView workFlowContainerView) {
        List<UserTaskDTO> userTaskList = workFlowContainerView.getUserTaskList();

        for (UserTaskDTO task : userTaskList) {
            if ("开发处理人（协同）".equals(task.getName())) {
                List<PdmUserDTO> userList = task.getUserList();
                if (CollUtil.isNotEmpty(userList)) {
                    return new BigInteger(userList.get(0).getOid());
                }
            }
        }
        return BigInteger.ZERO;
    }

    /**
     * 创建委托人角色映射
     */
    private Map<String, String> createEntrustorRoleMapping() {
        Map<String, String> map = new HashMap<>();
        map.put("委托人部长", "部长");
        map.put("委托人部长（审批）", "部长");
        map.put("委托人部门主管", "部门主管");
        map.put("委托人部门分管领导", "部门分管领导");
        return map;
    }

    /**
     * 创建开发处理人角色映射
     */
    private Map<String, String> createDeveloperRoleMapping() {
        Map<String, String> map = new HashMap<>();
        map.put("上节点部长（审批）", "部长");
        map.put("上节点部门主管", "部门主管");
        return map;
    }

    /**
     * 处理用户任务的核心逻辑
     */
    private void processUserTasks(WorkFlowContainerView workFlowContainerView,
                                  BigInteger baseUserId,
                                  Map<String, String> roleMapping,
                                  boolean includeBaseUser) {
        Set<BigInteger> userIdsToQuery = new HashSet<>();
        userIdsToQuery.add(baseUserId);

        // 获取部门信息
        List<String> deptIds = getUserDepartmentIds(baseUserId);
        if (CollUtil.isEmpty(deptIds)) {
            return;
        }

        // 获取部门角色映射
        Map<String, DeptRoleDO> roleMap = getDeptRoleMap(deptIds);

        // 收集需要查询的用户ID
        collectUserIdsFromTasks(workFlowContainerView.getUserTaskList(), roleMapping, roleMap, userIdsToQuery);

        // 批量查询用户信息
        if (CollUtil.isEmpty(userIdsToQuery)) {
            return;
        }

        Map<BigInteger, PdmUserDTO> userMap = batchQueryUsers(userIdsToQuery);

        // 分配用户到任务
        assignUsersToTasks(workFlowContainerView.getUserTaskList(), roleMapping, roleMap, userMap, baseUserId,
                           includeBaseUser);

        // 保存结果
        this.typlmFlowTaskUserService.insertUserTaskList(workFlowContainerView);
    }

    /**
     * 获取用户所属部门ID列表
     */
    private List<String> getUserDepartmentIds(BigInteger userId) {
        List<PrincipalEntity> outParent = typlmPrincipalService.getOneOutParentOrg(
                new PrincipalEntity(userId, TableTypeConstrant.TY_USER_OTYPE)
        );

        if (CollUtil.isEmpty(outParent)) {
            return Collections.emptyList();
        }

        return outParent.stream()
                .map(principal -> String.valueOf(principal.getOid()))
                .collect(Collectors.toList());
    }

    /**
     * 获取部门角色映射
     */
    private Map<String, DeptRoleDO> getDeptRoleMap(List<String> deptIds) {
        List<DeptRoleDO> deptRoleDOS = deptRoleMapper.selectDeptRoleDOListByDeptId(deptIds);

        return deptRoleDOS.stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toMap(
                        DeptRoleDO::getRoleName,
                        Function.identity(),
                        (existing, replacement) -> existing
                ));
    }

    /**
     * 从任务中收集需要查询的用户ID
     */
    private void collectUserIdsFromTasks(List<UserTaskDTO> userTaskList,
                                         Map<String, String> roleMapping,
                                         Map<String, DeptRoleDO> roleMap,
                                         Set<BigInteger> userIdsToQuery) {
        for (UserTaskDTO task : userTaskList) {
            String taskName = task.getName();
            String roleName = roleMapping.get(taskName);

            if (roleName != null) {
                DeptRoleDO deptRoleDO = roleMap.get(roleName);
                if (deptRoleDO != null && StringUtils.isNotBlank(deptRoleDO.getUserId())) {
                    userIdsToQuery.add(new BigInteger(deptRoleDO.getUserId()));
                }
            }
        }
    }

    /**
     * 批量查询用户信息
     */
    private Map<BigInteger, PdmUserDTO> batchQueryUsers(Set<BigInteger> userIds) {
        List<PdmUserDTO> allUsers = pdmUserService.getUserListByIds(new ArrayList<>(userIds));

        return allUsers.stream()
                .collect(Collectors.toMap(
                        u -> new BigInteger(u.getOid()),
                        Function.identity()
                ));
    }

    /**
     * 分配用户到任务
     */
    private void assignUsersToTasks(List<UserTaskDTO> userTaskList,
                                    Map<String, String> roleMapping,
                                    Map<String, DeptRoleDO> roleMap,
                                    Map<BigInteger, PdmUserDTO> userMap,
                                    BigInteger baseUserId,
                                    boolean includeBaseUser) {
        for (UserTaskDTO task : userTaskList) {
            String taskName = task.getName();
            List<PdmUserDTO> userList = task.getUserList();

            // 处理角色映射的用户
            String roleName = roleMapping.get(taskName);
            if (roleName != null) {
                DeptRoleDO deptRoleDO = roleMap.get(roleName);
                if (deptRoleDO != null && StringUtils.isNotBlank(deptRoleDO.getUserId())) {
                    BigInteger targetUserId = new BigInteger(deptRoleDO.getUserId());
                    PdmUserDTO user = userMap.get(targetUserId);
                    if (user != null) {
                        userList.add(user);
                        task.setUserList(userList);
                    }
                }
            }

            // 处理基础用户（委托人场景）
            if (includeBaseUser && "委托人".equals(taskName)) {
                PdmUserDTO user = userMap.get(baseUserId);
                if (user != null) {
                    userList.add(user);
                    task.setUserList(userList);
                }
            }
        }
    }

    public @NotNull WorkFlowObjectPackage getWorkFlowContainerView(List<UserTaskDTO> userTaskList, WorkFlow workFlow,
                                                                   List<FlowObject> flowObjectList,
                                                                   List<PdmUserDTO> userList, String workflowName) {
        WorkFlowObjectPackage containerView = new WorkFlowObjectPackage();

        containerView.setFlowObjectList(flowObjectList);

        containerView.setCodeNumber("WT" + System.currentTimeMillis());
        containerView.setOtype(TableTypeConstrant.TY_WORKFLOWCONTAINER_OTYPE);
        containerView.setName(workflowName);

        containerView.setWorkFlowId(workFlow.getOid());
        containerView.setWorkFlowName(workFlow.getName());
        containerView.setDeploymentId(workFlow.getDeploymentId());

        containerView.setUserTaskList(userTaskList);
        containerView.setEmergencyDegree("commonly");
        containerView.setContainerOid(flowObjectList.get(0).getContainerOid());
        containerView.setContainerOtype(flowObjectList.get(0).getContainerOtype());
        containerView.setBaseObjectOtype(ObjectTypeConstant.FLOW_OBJECT_PACKAGE);

        UserDO user = TyAccountContext.getUser();
        containerView.setCreatorOid(user.getOid());
        containerView.setCreatorOtype(TableTypeConstrant.TY_USER_OTYPE);
        containerView.setUpdaterOid(user.getOid());
        containerView.setUpdaterOtype(TableTypeConstrant.TY_USER_OTYPE);

        containerView.setManagerList(userList);
        return containerView;
    }

    @Override
    public void checkFromData(String workFlowContainerId, String expressionText) {
        WorkFlowContainerView workFlowContainerView = typlmWorkFlowContainerService.getWorkFlowContainerDetailByPrimaryKey(
                new BigInteger(workFlowContainerId));
        String formData = getFromDataByWorkFlowContainer(workFlowContainerView);
        JSONObject formDataJson = JSONObject.parseObject(formData);
        Map<String, String> keyValueMap = new HashMap<>();
        List<String> keyList = new ArrayList<>();
        // 按分号分割键值对
        String[] pairs = expressionText.split(";");
        for (String pair : pairs) {
            // 按第一个逗号分割key和value
            int commaIndex = pair.indexOf(',');
            if (commaIndex > 0) {
                String key = pair.substring(0, commaIndex).trim();
                String value = pair.substring(commaIndex + 1).trim();
                keyValueMap.put(key, value);
                keyList.add(key);
            }
        }
        Set<String> set = new HashSet<>();
        StringBuffer sb = new StringBuffer();
        processJsonObject(formDataJson, sb, keyValueMap, keyList, set);
        for (String key : keyList) {
            if (!set.contains(key)) {
                sb.append("【").append(keyValueMap.get(key)).append("】").append("为空").append(";");
            }
        }
        if (StringUtils.isNotBlank(sb.toString())) {
            throw RTErrorCodeEnum.DEV_CODE_EXIST.getException(sb.toString());
        }
    }

    @Override
    public void autoAddTaskListByFormData(String workFlowContainerId, String valueStr) {
        if (StringUtils.isBlank(valueStr)) {
            return;
        }
        WorkFlowContainerView workFlowContainerView = typlmWorkFlowContainerService
                .getWorkFlowContainerDetailByPrimaryKey(new BigInteger(workFlowContainerId));
        Map<String, String> fromDataAndTaskMap = parseValueStrToMap(valueStr);
        String formData = getFromDataByWorkFlowContainer(workFlowContainerView);
        JSONObject formDataJson = JSONObject.parseObject(formData);
        Map<String, IdentifierEntity> map = new HashMap<>();
        processJsonObject(formDataJson, fromDataAndTaskMap, map);

        Set<BigInteger> userIdsToQuery = map.values().stream()
                .filter(value -> TableTypeConstrant.TY_USER_OTYPE.equals(value.getOtype()))
                .map(IdentifierEntity::getOid)
                .collect(Collectors.toSet());

        Map<BigInteger, PdmUserDTO> userMap = batchQueryUsers(userIdsToQuery);

        List<UserTaskDTO> userTaskList = workFlowContainerView.getUserTaskList();
        for (UserTaskDTO userTaskDTO : userTaskList) {
            String name = userTaskDTO.getName();
            if (map.containsKey(name)) {
                IdentifierEntity identifierEntity = map.get(name);
                PdmUserDTO pdmUserDTO = userMap.get(identifierEntity.getOid());
                userTaskDTO.getUserList().add(pdmUserDTO);
            }
        }
        // 保存结果
        this.typlmFlowTaskUserService.insertUserTaskList(workFlowContainerView);
    }


    private void processJsonObject(JSONObject jsonObject, Map<String, String> fromDataAndTaskMap,
                                   Map<String, IdentifierEntity> map) {
        for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (value instanceof JSONObject) {
                JSONObject json = (JSONObject) value;
                if (fromDataAndTaskMap.containsKey(key)) {
                    String taskName = fromDataAndTaskMap.get(key);
                    map.put(taskName, new IdentifierEntity(json.getBigInteger("oid"), json.getString("otype")));
                }
                processJsonObject(json, fromDataAndTaskMap, map); // 递归处理嵌套对象
            } else if (value instanceof JSONArray) {
                processJsonArray((JSONArray) value, fromDataAndTaskMap, map); // 处理数组
            }
        }
    }

    private void processJsonArray(JSONArray jsonArray, Map<String, String> fromDataAndTaskMap,
                                  Map<String, IdentifierEntity> map) {
        for (Object item : jsonArray) {
            if (item == null) {
                continue;
            }
            if (item instanceof JSONObject) {
                processJsonObject((JSONObject) item, fromDataAndTaskMap, map);
            } else if (item instanceof JSONArray) {
                processJsonArray((JSONArray) item, fromDataAndTaskMap, map);
            }
        }
    }


    /**
     * 将valueStr解析为Map结构
     * 格式：内部名称1=节点名称1;内部名称2=节点名称2
     *
     * @param valueStr 输入的字符串
     * @return 解析后的Map，key为内部名称，value为节点名称
     */
    private Map<String, String> parseValueStrToMap(String valueStr) {
        Map<String, String> resultMap = new HashMap<>();
        if (StringUtils.isBlank(valueStr)) {
            return resultMap;
        }
        // 按分号分割每一对键值
        String[] pairs = valueStr.split(";");

        for (String pair : pairs) {
            if (StringUtils.isNotBlank(pair)) {
                // 按等号分割key和value
                int equalIndex = pair.indexOf('=');
                if (equalIndex > 0) {
                    String internalName = pair.substring(0, equalIndex).trim();
                    String nodeName = pair.substring(equalIndex + 1).trim();
                    resultMap.put(internalName, nodeName);
                }
            }
        }

        return resultMap;
    }


    private void processJsonObject(JSONObject jsonObject, StringBuffer error, Map<String, String> keyValueMap,
                                   List<String> keyList, Set<String> set) {
        for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
            String key = entry.getKey();
            set.add(key);
            Object value = entry.getValue();
            if (value == null) {
                if (keyList.contains(key)) {
                    error.append("【").append(keyValueMap.get(key)).append("】").append("为空").append(";");
                }
                continue;
            }
            if (value instanceof JSONObject) {
                processJsonObject((JSONObject) value, error, keyValueMap, keyList, set); // 递归处理嵌套对象
            } else if (value instanceof JSONArray) {
                processJsonArray(key, (JSONArray) value, error, keyValueMap, keyList, set); // 处理数组
            } else if (value instanceof String || value instanceof Number || value instanceof Boolean) {
                if (StringUtils.isBlank(value.toString())) {
                    if (keyList.contains(key)) {
                        error.append("【").append(keyValueMap.get(key)).append("】").append("为空").append(";");
                    }
                }
            }
        }
    }

    private void processJsonArray(String key, JSONArray jsonArray, StringBuffer error, Map<String, String> keyValueMap,
                                  List<String> keyList, Set<String> set) {
        for (Object item : jsonArray) {
            if (item == null) {
                if (keyList.contains(key)) {
                    error.append("【").append(keyValueMap.get(key)).append("】").append("为空").append(";");
                }
                continue;
            }
            if (item instanceof JSONObject) {
                processJsonObject((JSONObject) item, error, keyValueMap, keyList, set);
            } else if (item instanceof JSONArray) {
                processJsonArray(key, (JSONArray) item, error, keyValueMap, keyList, set);
            }
        }
    }

    private JSONObject getFromDataByWorkFlowContainer(WorkFlowContainerView workFlowContainerView, boolean isTemplate) {
        JSONObject data = new JSONObject();
        if ((workFlowContainerView instanceof WorkFlowObjectPackage)) {
            log.info("当前流程属于普通流程");
            WorkFlowObjectPackage workFlowObjectPackage = (WorkFlowObjectPackage) workFlowContainerView;
            List<FlowObject> flowObjectList = workFlowObjectPackage.getFlowObjectList();
            String refObjectOtype = flowObjectList.get(0).getRefObjectOtype();
            if (TableTypeConstrant.TY_FORMDATA_TYPE.equalsIgnoreCase(refObjectOtype)) {
                BigInteger refObjectOid = flowObjectList.get(0).getRefObjectOid();
                TyplmFormDataVO formDataVO = this.tyFormDataExtService.getFormDataDetail(refObjectOid);
                data.put("formData", formDataVO.getFormdata());
                if (isTemplate) {
                    data.put("template", JSONObject.parseObject(formDataVO.getTemplatedata()));
                }
            }
        } else if (workFlowContainerView instanceof FlowChgFormView) {
            log.info("当前流程属于变更流程/发布流程");
            FlowChgFormView flowChgFormView = (FlowChgFormView) workFlowContainerView;
            JSONObject formData = JSONObject.parseObject(flowChgFormView.getChgFormVO().getFormData());
            data.put("formData", formData);
            if (isTemplate) {
                JSONObject templateData = JSONObject.parseObject(flowChgFormView.getChgFormVO().getFormtemplateData());
                data.put("template", templateData);
            }
        } else if (workFlowContainerView instanceof FlowChangeRequestView) {
            log.info("当前流程属于变更请求流程");
            FlowChangeRequestView flowChangeRequestView = (FlowChangeRequestView) workFlowContainerView;
            JSONObject formData = JSONObject.parseObject(flowChangeRequestView.getChgRequestDetailVO().getFormData());
            data.put("formData", formData);
            if (isTemplate) {
                JSONObject templateData = JSONObject.parseObject(
                        flowChangeRequestView.getChgRequestDetailVO().getFormtemplateData());
                data.put("template", templateData);
            }
        } else if (workFlowContainerView instanceof FlowChangeIssueView) {
            log.info("当前流程属于变更问题流程");
            FlowChangeIssueView flowChangeIssueView = (FlowChangeIssueView) workFlowContainerView;
            JSONObject formData = JSONObject.parseObject(flowChangeIssueView.getChangeIssueDTO().getFormData());
            data.put("formData", formData);
            if (isTemplate) {
                JSONObject templateData = JSONObject.parseObject(
                        flowChangeIssueView.getChangeIssueDTO().getFormtemplateData());
                data.put("template", templateData);
            }
        }
        return data;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public IdentifierEntity startPlanChangWorkFlow(JSONObject param) {
        BigInteger containerOid = param.getBigInteger("projectOid");
        String containerOtype = TableTypeConstrant.TY_PROJECT_TYPE;
        WorkFlow workFlow = flowControlService.getDefaultWorkFlow("项目计划变更流程模板");
        List<PdmUserDTO> userList = flowControlService.getPdmUserDTOS(Collections.singletonList("admin"));
        List<UserTaskDTO> allUserTask = typlmWorkFlowContainerService.getAllUserTask(workFlow.getOid(), containerOid,
                                                                                     containerOtype);
        if (CollUtil.isNotEmpty(userList)) {
            for (UserTaskDTO userTaskDTO : allUserTask) {
                userTaskDTO.setUserList(userList);
            }
        }
        List<String> projectNameList = projectCodeMapper.selectProjectNameByChgId(param.getString("changeInfoOid"));
        String workFlowName = CollUtil.isNotEmpty(projectNameList) ? projectNameList.get(
                0) + "项目变更审批流程" : "项目变更审批流程";
        WorkFlowContainerView containerView = buildProjectWorkFlowContainerView(allUserTask, workFlow, userList,
                                                                                workFlowName, param);
        this.typlmWorkFlowProcessService.startProcess(containerView, true);
        return containerView.getIdentifierRef();
    }

    private WorkFlowContainerView buildProjectWorkFlowContainerView(List<UserTaskDTO> allUserTask, WorkFlow workFlow,
                                                                    List<PdmUserDTO> userList, String workFlowName,
                                                                    JSONObject param) {

        WorkFlowContainerView containerView = new WorkFlowContainerView();
        String code = param.getString("code");
        containerView.setCodeNumber(code);
        containerView.setCode(code);
        containerView.setName(workFlowName);
        containerView.setWorkFlowId(workFlow.getOid());
        containerView.setWorkFlowName(workFlow.getName());
        containerView.setDeploymentId(workFlow.getDeploymentId());
        containerView.setUserTaskList(allUserTask);
        containerView.setEmergencyDegree("commonly");
        UserDO user = TyAccountContext.getUser();
        containerView.setCreatorOid(user.getOid());
        containerView.setCreatorOtype(TableTypeConstrant.TY_USER_OTYPE);
        containerView.setUpdaterOid(user.getOid());
        containerView.setUpdaterOtype(TableTypeConstrant.TY_USER_OTYPE);
        containerView.setManagerList(userList);
        containerView.setBaseObjectOid(param.getBigInteger("changeInfoOid"));
        containerView.setBaseObjectOtype(TableTypeConstrant.TY_PJ_CHANGEINFO_OTYPE);
        containerView.setContainerOid(param.getBigInteger("projectOid"));
        containerView.setContainerOtype(TableTypeConstrant.TY_PROJECT_TYPE);
        containerView.setWorkFlowOtype(TableTypeConstrant.TY_WORKFLOW_OTYPE);
        containerView.setOtype(TableTypeConstrant.TY_WORKFLOWCONTAINER_OTYPE);
        containerView.setType("项目计划变更");
        TyplmWorkFlowContainerInstanceService instanceService = this.getInstanceService(
                containerView.getBaseObjectOtype());
        instanceService.createContainerView(containerView);
        List<IdentifierEntity> entityList = containerView.getReferenceList();
        List<WorkFlowContainerReferenceLink> linkList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(entityList)) {
            entityList.forEach((item) -> {
                WorkFlowContainerReferenceLink link = new WorkFlowContainerReferenceLink();
                link.setAoid(containerView.getOid());
                link.setAotype(containerView.getOtype());
                link.setBoid(item.getOid());
                link.setBotype(item.getOtype());
                linkList.add(link);
            });
            this.typlmWorkFlowContainerViewExtendService.batchInsertReference(linkList);
        }

        TyplmAuditLogUtil.info(containerView.getOid(), containerView.getOtype(), LogEventEnum.CRATE_OBJECT);
        return containerView;
    }

    private TyplmWorkFlowContainerInstanceService getInstanceService(String otype) {
        Class<? extends TyplmWorkFlowContainerInstanceService> aClass = ContainerInstanceFactory.getClassByOtype(otype);
        if (null == aClass) {
            TyplmLoggerUtil.debug(log, () -> "getInstanceService ==> otype : 【{}】", () -> new Object[]{otype});
            aClass = TyplmWorkFlowContainerInstanceDefaultServiceImpl.class;
        }

        TyplmWorkFlowContainerInstanceService instance = SpringUtil.getBean(aClass);
        if (null == instance) {
            throw SystemErrorCodeEnum.WORK_FLOW_CONTAINER_NO_IMPLEMENT.getException();
        } else {
            return instance;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void completedPlanChangWorkFlow(JSONObject param) throws Exception {
        // 参数校验
        ArgumentUtils.checkArgumentNull(param.getString("route"), "route");
        ArgumentUtils.checkArgumentNull(param.getString("workFlowContainerId"), "workFlowContainerId");

        String key = "adapter:lock:workflow:" + param.getString("workFlowContainerId");
        boolean hasLocked = this.typlmRedisLockService.hasLocked(key);
        if (hasLocked) {
            throw WorkFlowErrorCodeEnum.TASK_DO_NOT_SUBMIT_REPEATEDLY.getException();
        } else {
            try {
                this.typlmRedisLockService.lock(key);
                // 根据流程容器id查询当前节点信息
                Map<String, List<FlowTaskInfo>> currentUserTaskMap = this.typlmWorkFlowContainerService.queryTaskByFlowContainer(
                        param.getBigInteger("workFlowContainerId"));
                List<FlowTaskInfo> taskInfoList = new ArrayList<>();
                for (List<FlowTaskInfo> tasks : currentUserTaskMap.values()) {
                    if (tasks != null && !tasks.isEmpty()) {
                        taskInfoList.addAll(tasks);
                    }
                }

                //根据任务ID获取任务详情
                FlowTaskInfo flowTaskInfo = taskInfoList.get(0);
                String taskId = flowTaskInfo.getTaskId();
                FlowTaskInfo taskDetailView = this.typlmWorkFlowProcessService.getTaskDetailView(taskId);
                this.typlmWorkFlowtOperateTaskService.setFlowNodeInfo(taskDetailView, null, "flowTask");

                //获取Oa路由信息
                List<Router> routerList = taskDetailView.getRouterList();
                String route = param.getString("route");
                Optional<Router> optional = routerList.stream().filter(item -> route.equals(item.getLabel()))
                        .findFirst();
                if (optional.isPresent()) {
                    // 完成任务
                    JSONObject flowTaskInfoObj = (JSONObject) JSONObject.toJSON(flowTaskInfo);
                    taskDetailView.setViewObject(flowTaskInfoObj);
                    taskDetailView.setRouterCheckList(Collections.singletonList(optional.get().getValue()));
                    this.typlmWorkFlowProcessService.completeTask(taskDetailView, null);
                } else {
                    throw RTErrorCodeEnum.WORK_FLOW_EXECUTE_EXCEPTION.getException("未获取到正确的路由信息");
                }
            } finally {
                this.typlmRedisLockService.unlock(key);
            }
        }
    }

    @Resource
    private ProjectMapper projectMapper;

    @Override
    public void updateProjectChangeFlowName(String workFlowContainerId) {
        WorkFlowContainerView workFlowContainerView = typlmWorkFlowContainerService.getWorkFlowContainerDetailByPrimaryKey(
                new BigInteger(workFlowContainerId));
        String baseObjectOtype = workFlowContainerView.getBaseObjectOtype();
        if (TableTypeConstrant.TY_PJ_CHANGEINFO_OTYPE.equals(baseObjectOtype)) {
            BigInteger baseObjectOid = workFlowContainerView.getBaseObjectOid();
            List<String> projectNameList = projectCodeMapper.selectProjectNameByChgId(baseObjectOid.toString());
            if (CollUtil.isNotEmpty(projectNameList)) {
                String name = "\"" + projectNameList.get(0) + "\" 项目变更审批流程";
                projectMapper.updateFlowContainerNameByOid(workFlowContainerId, name);
            }
        }
    }

    /**
     * 校验编码启用流程
     *
     * @param workFlowContainerId
     */
    @Override
    public void codeEnableProcessValidation(BigInteger workFlowContainerId) {
        WorkFlowContainerView workFlowContainerView = typlmWorkFlowContainerService.getWorkFlowContainerDetailByPrimaryKey(
                workFlowContainerId);
        if ((workFlowContainerView instanceof WorkFlowObjectPackage)) {
            WorkFlowObjectPackage workFlowObjectPackage = (WorkFlowObjectPackage) workFlowContainerView;
            List<FlowObject> flowObjectList = workFlowObjectPackage.getFlowObjectList();
            if (CollUtil.isNotEmpty(flowObjectList)) {
                List<IdentifierEntity> flowList = flowObjectList.stream().map(
                        m -> new IdentifierEntity(m.getRefObjectOid(), m.getRefObjectOtype())).distinct().collect(
                        Collectors.toList());
                List<BigInteger> partOidS = flowList.stream().map(IdentifierEntity::getOid).distinct().collect(
                        Collectors.toList());
                List<TyPartAllVO> tyPartAllVOS = typlmPartService.queryPartAllVOList(partOidS);
                Set<String> partNumberS = new HashSet<>();
                List<String> partNumberList = new ArrayList<>();
                for (TyPartAllVO tyPartAllVO : tyPartAllVOS) {
                    String typeName = tyPartAllVO.getTypeName();
                    String masterPartNumber = tyPartAllVO.getMasterPartNumber();
                    //物料码
                    if ("MaterialCode".equals(typeName)) {
                        String partNumber = masterPartNumber.substring(0, 13);
                        partNumberS.add(partNumber);
                    } else if ("PatternCode".equals(typeName)) { //图样代号
                        partNumberList.add(masterPartNumber);
                    }
                }
                if (CollUtil.isEmpty(partNumberS)) {
                    return;
                }
                List<PartDO> partDOS = rtPartMapper.queryLatestPartByNumberList(new ArrayList<>(partNumberS), "");
                List<String> errorList = new ArrayList<>();
                for (PartDO partDO : partDOS) {
                    String lifecyclestagekey = partDO.getLifecyclestagekey();
                    //已生效   生效未出图
                    boolean isUnreleasedOrInvalid = !"RELEASED".equals(lifecyclestagekey) && !"EffectiveNot".equals(lifecyclestagekey);
                    if (isUnreleasedOrInvalid && !partNumberList.contains(partDO.getPartnumber())) {
                        errorList.add(partDO.getPartnumber());
                    }
                }
                if (CollUtil.isNotEmpty(errorList)) {
                    throw RTErrorCodeEnum.CHECK_EBOM_ERROR.getException(
                            "图样代号不为：" + errorList + "，请添加到流程中！");
                }
            }
        }
    }

//    @Override
//    public void checkWorkFlowPartData(BigInteger workFlowContainerId) {
//        WorkFlowContainerView workFlowContainerView = typlmWorkFlowContainerService.getWorkFlowContainerDetailByPrimaryKey(
//                workFlowContainerId);
//        if (!(workFlowContainerView instanceof WorkFlowObjectPackage)) {
//            return;
//        }
//
//        WorkFlowObjectPackage workFlowObjectPackage = (WorkFlowObjectPackage) workFlowContainerView;
//        List<FlowObject> flowObjectList = workFlowObjectPackage.getFlowObjectList();
//        if (CollUtil.isEmpty(flowObjectList)) {
//            return;
//        }
//
//        List<IdentifierEntity> flowList = flowObjectList.stream()
//                .map(m -> new IdentifierEntity(m.getRefObjectOid(), m.getRefObjectOtype()))
//                .distinct()
//                .collect(Collectors.toList());
//        List<BigInteger> partOidS = flowList.stream()
//                .map(IdentifierEntity::getOid)
//                .distinct()
//                .collect(Collectors.toList());
//
//        if (CollUtil.isEmpty(partOidS)) {
//            return;
//        }
//
//        Map<String, List<AttributeVO>> ibaValuePart = typlmAttributeValueService.getAttrValueTableByEntitys(
//                partOidS, TableTypeConstrant.TY_PART_OTYPE);
//        List<TyPartAllVO> tyPartAllVOS = typlmPartService.queryPartAllVOList(partOidS);
//        Map<BigInteger, StdTypeDetailDTO> typeData = rtOaFormMappingService.getTypeData(
//                Arrays.asList("ty.inteplm.cad.CTyCADDoc", "DesignDrawings"));
//        Map<BigInteger, List<CADDocDO>> cadMap = typlmPartRelObjectService.batchQueryLinkCadMapByPartList(partOidS);
//        List<PartDescribeDocVO> partDescribeDocVOS = typlmPartDescribeLinkService.batchQueryLatestDescribeDocByPartOids(
//                partOidS, null);
//        Map<BigInteger, List<PartDescribeDocVO>> partDocMap = partDescribeDocVOS.stream()
//                .collect(Collectors.groupingBy(PartDescribeDocVO::getPartOid));
//
//        StringBuffer errorMsg = new StringBuffer();
//
//        for (TyPartAllVO tyPartAllVO : tyPartAllVOS) {
//            String typeName = tyPartAllVO.getTypeName();
//            if (!"PatternCode".equals(typeName)) {
//                continue;
//            }
//
//            List<AttributeVO> attributeVOS = ibaValuePart.get(tyPartAllVO.getOid().toString());
//            if (CollUtil.isEmpty(attributeVOS)) {
//                continue;
//            }
//
//            Map<String, String> ibaValueMap = attributeVOS.stream()
//                    .filter(attr -> attr != null
//                            && attr.getAttributeEnName() != null
//                            && attr.getAttributeValue() != null)
//                    .collect(Collectors.toMap(
//                            AttributeVO::getAttributeEnName,
//                            AttributeVO::getAttributeValue,
//                            (oldValue, newValue) -> newValue
//                    ));
//
//            String value = ibaValueMap.get("OutputRequirements");
//            if (StringUtils.isBlank(value)) {
//                continue;
//            }
//
//            switch (value) {
//                case "1":
//                    // 2D: 二维图纸或者设计文档
//                    if (!has2DDrawingOrDesignDoc(tyPartAllVO, cadMap, partDocMap, typeData)) {
//                        errorMsg.append(tyPartAllVO.getPartnumber()).append("不存在对应的二维图纸或者设计文档！");
//                    }
//                    break;
//                case "2":
//                    // 2D/3D: 二维图纸或者三维数模或者设计文档
//                    if (!has2DOr3DDrawingOrDesignDoc(tyPartAllVO, cadMap, partDocMap, typeData)) {
//                        errorMsg.append(tyPartAllVO.getPartnumber()).append(
//                                "不存在对应的二维图纸或者三维数模或者设计文档！");
//                    }
//                    break;
//                case "3":
//                    // 3D: 三维数模
//                    if (!has3DDrawing(tyPartAllVO, cadMap, typeData)) {
//                        errorMsg.append(tyPartAllVO.getPartnumber()).append("不存在对应的三维数模！");
//                    }
//                    break;
//                case "4":
//                    // 封样: 设计文档
//                    if (!hasDesignDoc(tyPartAllVO, partDocMap, typeData)) {
//                        errorMsg.append(tyPartAllVO.getPartnumber()).append("不存在对应的设计图纸！");
//                    }
//                    break;
//                case "5":
//                    // 2D/封样: 二维图纸或者设计图纸
//                    if (!has2DDrawingOrDesignDrawing(tyPartAllVO, cadMap, partDocMap, typeData)) {
//                        errorMsg.append(tyPartAllVO.getPartnumber()).append("不存在对应的二维图纸或者设计图纸！");
//                    }
//                    break;
//                default:
//                    break;
//            }
//        }
//
//        if (errorMsg.length() > 0) {
//            throw RTErrorCodeEnum.DRAWING_CODE_NAME_ERROR.getException(errorMsg.toString());
//        }
//    }
//
//    /**
//     * 检查是否存在二维图纸或设计文档
//     */
//    private boolean has2DDrawingOrDesignDoc(TyPartAllVO part, Map<BigInteger, List<CADDocDO>> cadMap,
//                                            Map<BigInteger, List<PartDescribeDocVO>> partDocMap,
//                                            Map<BigInteger, StdTypeDetailDTO> typeData) {
//        // 检查CAD文档
//        List<CADDocDO> cadDocDOS = cadMap.get(part.getOid());
//        if (CollUtil.isNotEmpty(cadDocDOS)) {
//            for (CADDocDO cadDocDO : cadDocDOS) {
//                BigInteger typeOid = cadDocDO.getTypeoid();
//                StdTypeDetailDTO stdTypeDetailDTO = typeData.get(typeOid);
//                if (stdTypeDetailDTO != null && stdTypeDetailDTO.getInthid() != null &&
//                        stdTypeDetailDTO.getInthid().contains("二维图纸")) {
//                    return true;
//                }
//            }
//        }
//
//        // 检查描述文档
//        List<PartDescribeDocVO> partDescribeDocVOS = partDocMap.get(part.getOid());
//        if (CollUtil.isNotEmpty(partDescribeDocVOS)) {
//            for (PartDescribeDocVO partDescribeDocVO : partDescribeDocVOS) {
//                BigInteger typeOid = partDescribeDocVO.getTypeoid();
//                StdTypeDetailDTO stdTypeDetailDTO = typeData.get(typeOid);
//                if (stdTypeDetailDTO != null && stdTypeDetailDTO.getInthid() != null &&
//                        stdTypeDetailDTO.getInthid().contains("设计图纸")) {
//                    return true;
//                }
//            }
//        }
//
//        return false;
//    }
//
//    /**
//     * 检查是否存在二维图纸、三维数模或设计文档
//     */
//    private boolean has2DOr3DDrawingOrDesignDoc(TyPartAllVO part, Map<BigInteger, List<CADDocDO>> cadMap,
//                                                Map<BigInteger, List<PartDescribeDocVO>> partDocMap,
//                                                Map<BigInteger, StdTypeDetailDTO> typeData) {
//        boolean has2D = false;
//        boolean has3D = false;
//
//        // 检查CAD文档
//        List<CADDocDO> cadDocDOS = cadMap.get(part.getOid());
//        if (CollUtil.isNotEmpty(cadDocDOS)) {
//            for (CADDocDO cadDocDO : cadDocDOS) {
//                BigInteger typeOid = cadDocDO.getTypeoid();
//                StdTypeDetailDTO stdTypeDetailDTO = typeData.get(typeOid);
//                if (stdTypeDetailDTO != null && stdTypeDetailDTO.getInthid() != null) {
//                    String inthid = stdTypeDetailDTO.getInthid();
//                    if (inthid.contains("二维图纸")) {
//                        has2D = true;
//                    } else if (inthid.contains("三维图纸")) {
//                        has3D = true;
//                    }
//                }
//            }
//        }
//
//        // 检查描述文档
//        List<PartDescribeDocVO> partDescribeDocVOS = partDocMap.get(part.getOid());
//        if (CollUtil.isNotEmpty(partDescribeDocVOS)) {
//            for (PartDescribeDocVO partDescribeDocVO : partDescribeDocVOS) {
//                BigInteger typeOid = partDescribeDocVO.getTypeoid();
//                StdTypeDetailDTO stdTypeDetailDTO = typeData.get(typeOid);
//                if (stdTypeDetailDTO != null && stdTypeDetailDTO.getInthid() != null &&
//                        stdTypeDetailDTO.getInthid().contains("设计图纸")) {
//                    has2D = true;
//                }
//            }
//        }
//
//        return has2D || has3D;
//    }
//
//    /**
//     * 检查是否存在三维数模
//     */
//    private boolean has3DDrawing(TyPartAllVO part, Map<BigInteger, List<CADDocDO>> cadMap,
//                                 Map<BigInteger, StdTypeDetailDTO> typeData) {
//        List<CADDocDO> cadDocDOS = cadMap.get(part.getOid());
//        if (CollUtil.isNotEmpty(cadDocDOS)) {
//            for (CADDocDO cadDocDO : cadDocDOS) {
//                BigInteger typeOid = cadDocDO.getTypeoid();
//                StdTypeDetailDTO stdTypeDetailDTO = typeData.get(typeOid);
//                if (stdTypeDetailDTO != null && stdTypeDetailDTO.getInthid() != null &&
//                        stdTypeDetailDTO.getInthid().contains("三维图纸")) {
//                    return true;
//                }
//            }
//        }
//        return false;
//    }
//
//    /**
//     * 检查是否存在设计文档
//     */
//    private boolean hasDesignDoc(TyPartAllVO part, Map<BigInteger, List<PartDescribeDocVO>> partDocMap,
//                                 Map<BigInteger, StdTypeDetailDTO> typeData) {
//        List<PartDescribeDocVO> partDescribeDocVOS = partDocMap.get(part.getOid());
//        if (CollUtil.isNotEmpty(partDescribeDocVOS)) {
//            for (PartDescribeDocVO partDescribeDocVO : partDescribeDocVOS) {
//                BigInteger typeOid = partDescribeDocVO.getTypeoid();
//                StdTypeDetailDTO stdTypeDetailDTO = typeData.get(typeOid);
//                if (stdTypeDetailDTO != null && stdTypeDetailDTO.getInthid() != null &&
//                        stdTypeDetailDTO.getInthid().contains("设计图纸")) {
//                    return true;
//                }
//            }
//        }
//        return false;
//    }
//
//    /**
//     * 检查是否存在二维图纸或设计图纸
//     */
//    private boolean has2DDrawingOrDesignDrawing(TyPartAllVO part, Map<BigInteger, List<CADDocDO>> cadMap,
//                                                Map<BigInteger, List<PartDescribeDocVO>> partDocMap,
//                                                Map<BigInteger, StdTypeDetailDTO> typeData) {
//        boolean has2D = false;
//        boolean hasDoc = false;
//
//        // 检查CAD文档中的二维图纸
//        List<CADDocDO> cadDocDOS = cadMap.get(part.getOid());
//        if (CollUtil.isNotEmpty(cadDocDOS)) {
//            for (CADDocDO cadDocDO : cadDocDOS) {
//                BigInteger typeOid = cadDocDO.getTypeoid();
//                StdTypeDetailDTO stdTypeDetailDTO = typeData.get(typeOid);
//                if (stdTypeDetailDTO != null && stdTypeDetailDTO.getInthid() != null &&
//                        stdTypeDetailDTO.getInthid().contains("二维图纸")) {
//                    has2D = true;
//                }
//            }
//        }
//
//        // 检查描述文档中的设计图纸
//        List<PartDescribeDocVO> partDescribeDocVOS = partDocMap.get(part.getOid());
//        if (CollUtil.isNotEmpty(partDescribeDocVOS)) {
//            for (PartDescribeDocVO partDescribeDocVO : partDescribeDocVOS) {
//                BigInteger typeOid = partDescribeDocVO.getTypeoid();
//                StdTypeDetailDTO stdTypeDetailDTO = typeData.get(typeOid);
//                if (stdTypeDetailDTO != null && stdTypeDetailDTO.getInthid() != null &&
//                        stdTypeDetailDTO.getInthid().contains("设计图纸")) {
//                    hasDoc = true;
//                }
//            }
//        }
//
//        return has2D || hasDoc;
//    }

        @Override
        public void checkWorkFlowPartData(BigInteger workFlowContainerId) {
            WorkFlowContainerView workFlowContainerView = typlmWorkFlowContainerService.getWorkFlowContainerDetailByPrimaryKey(workFlowContainerId);
            if ((workFlowContainerView instanceof WorkFlowObjectPackage)) {
                WorkFlowObjectPackage workFlowObjectPackage = (WorkFlowObjectPackage) workFlowContainerView;
                List<FlowObject> flowObjectList = workFlowObjectPackage.getFlowObjectList();
                if (CollUtil.isNotEmpty(flowObjectList)) {
                    List<IdentifierEntity> flowList = flowObjectList.stream().map(
                            m -> new IdentifierEntity(m.getRefObjectOid(), m.getRefObjectOtype())).distinct().collect(
                            Collectors.toList());
                    List<BigInteger> partOidS = flowList.stream().map(IdentifierEntity::getOid).distinct().collect(
                            Collectors.toList());
                    Map<String, List<AttributeVO>> ibaValuePart = typlmAttributeValueService.getAttrValueTableByEntitys(
                            partOidS, TableTypeConstrant.TY_PART_OTYPE);
                    List<TyPartAllVO> tyPartAllVOS = typlmPartService.queryPartAllVOList(partOidS);
                    Map<BigInteger, StdTypeDetailDTO> typeData = rtOaFormMappingService.getTypeData(
                            Arrays.asList("ty.inteplm.cad.CTyCADDoc", "DesignDrawings"));
                    Map<BigInteger, List<CADDocDO>> cadMap = typlmPartRelObjectService.batchQueryLinkCadMapByPartList(
                            partOidS);
                    List<PartDescribeDocVO> partDescribeDocVOS = typlmPartDescribeLinkService.batchQueryLatestDescribeDocByPartOids(
                            partOidS, null);
                    Map<BigInteger, List<PartDescribeDocVO>> partDocMap = partDescribeDocVOS.stream()
                            .collect(Collectors.groupingBy(PartDescribeDocVO::getPartOid));
                    StringBuffer errorMsg = new StringBuffer();
                    for(TyPartAllVO tyPartAllVO : tyPartAllVOS) {
                        String typeName = tyPartAllVO.getTypeName();
                        if("PatternCode".equals(typeName)){
                            List<AttributeVO> attributeVOS = ibaValuePart.get(tyPartAllVO.getOid().toString());
                            Map<String, String> ibaValueMap = attributeVOS.stream()
                                    .filter(attr -> attr != null
                                            && attr.getAttributeEnName() != null
                                            && attr.getAttributeValue() != null)
                                    .collect(Collectors.toMap(
                                            AttributeVO::getAttributeEnName,
                                            AttributeVO::getAttributeValue,
                                            (oldValue, newValue) -> newValue
                                    ));
                            String value = ibaValueMap.get("OutputRequirements");
                            //2D  二维图纸或者设计文档
                            //3D  三维数模
                            //封样 设计文档
                            if(StringUtils.isNotBlank(value)){
                                if ("1".equals(value)) {
                                    //2D
                                    boolean flag = false;
                                    List<CADDocDO> cadDocDOS = cadMap.get(tyPartAllVO.getOid());
                                    for(CADDocDO cadDocDO : cadDocDOS){
                                        BigInteger typeOid = cadDocDO.getTypeoid();
                                        StdTypeDetailDTO stdTypeDetailDTO = typeData.get(typeOid);
                                        String inthid = stdTypeDetailDTO.getInthid();
                                        if(inthid.contains("二维图纸")){
                                            flag = true;
                                        }
                                    }
                                    List<PartDescribeDocVO> partDescribeDocVOS1 = partDocMap.get(tyPartAllVO.getOid());
                                    for(PartDescribeDocVO partDescribeDocVO : partDescribeDocVOS1){
                                        BigInteger typeOid = partDescribeDocVO.getTypeoid();
                                        StdTypeDetailDTO stdTypeDetailDTO = typeData.get(typeOid);
                                        String inthid = stdTypeDetailDTO.getInthid();
                                        if(inthid.contains("设计图纸")){
                                            flag = true;
                                        }
                                    }
                                    if(!flag){
                                        errorMsg.append(tyPartAllVO.getMasterPartNumber()).append(
                                                "不存在对应的二维图纸或者设计文档！");
                                    }
                                } else if ("2".equals(value)) {
                                    //2D/3D
                                    boolean flag2d = false;
                                    boolean flag3d = false;
                                    List<CADDocDO> cadDocDOS = cadMap.get(tyPartAllVO.getOid());
                                    for(CADDocDO cadDocDO : cadDocDOS){
                                        BigInteger typeOid = cadDocDO.getTypeoid();
                                        StdTypeDetailDTO stdTypeDetailDTO = typeData.get(typeOid);
                                        String inthid = stdTypeDetailDTO.getInthid();
                                        if(inthid.contains("二维图纸")){
                                            flag2d = true;
                                        }else if(inthid.contains("三维图纸")){
                                            flag3d = true;
                                        }
                                    }
                                    List<PartDescribeDocVO> partDescribeDocVOS1 = partDocMap.get(tyPartAllVO.getOid());
                                    for(PartDescribeDocVO partDescribeDocVO : partDescribeDocVOS1){
                                        BigInteger typeOid = partDescribeDocVO.getTypeoid();
                                        StdTypeDetailDTO stdTypeDetailDTO = typeData.get(typeOid);
                                        String inthid = stdTypeDetailDTO.getInthid();
                                        if(inthid.contains("设计图纸")){
                                            flag2d = true;
                                        }
                                    }
                                    if(!flag2d || !flag3d){
                                        errorMsg.append(tyPartAllVO.getMasterPartNumber()).append(
                                                "不存在对应的二维图纸或者三维数模或者设计文档！");
                                    }
                                } else if ("3".equals(value)) {
                                    //3D
                                    boolean flag3d = false;
                                    List<CADDocDO> cadDocDOS = cadMap.get(tyPartAllVO.getOid());
                                    for(CADDocDO cadDocDO : cadDocDOS){
                                        BigInteger typeOid = cadDocDO.getTypeoid();
                                        StdTypeDetailDTO stdTypeDetailDTO = typeData.get(typeOid);
                                        String inthid = stdTypeDetailDTO.getInthid();
                                        if(inthid.contains("三维图纸")){
                                            flag3d = true;
                                        }
                                    }

                                    if(!flag3d){
                                        errorMsg.append(tyPartAllVO.getMasterPartNumber()).append(
                                                "不存在对应的三维数模！");
                                    }
                                } else if ("4".equals(value)) {
                                    //封样
                                    boolean flag2d = false;
                                    List<PartDescribeDocVO> partDescribeDocVOS1 = partDocMap.get(tyPartAllVO.getOid());
                                    for(PartDescribeDocVO partDescribeDocVO : partDescribeDocVOS1){
                                        BigInteger typeOid = partDescribeDocVO.getTypeoid();
                                        StdTypeDetailDTO stdTypeDetailDTO = typeData.get(typeOid);
                                        String inthid = stdTypeDetailDTO.getInthid();
                                        if(inthid.contains("设计图纸")){
                                            flag2d = true;
                                        }
                                    }
                                    if(!flag2d){
                                        errorMsg.append(tyPartAllVO.getMasterPartNumber()).append(
                                                "不存在对应的设计图纸！");
                                    }
                                } else if ("5".equals(value)) {
                                    //2D/封样
                                    boolean flag2d = false;
                                    boolean flagDoc = false;
                                    List<CADDocDO> cadDocDOS = cadMap.get(tyPartAllVO.getOid());
                                    for(CADDocDO cadDocDO : cadDocDOS){
                                        BigInteger typeOid = cadDocDO.getTypeoid();
                                        StdTypeDetailDTO stdTypeDetailDTO = typeData.get(typeOid);
                                        String inthid = stdTypeDetailDTO.getInthid();
                                        if(inthid.contains("二维图纸")){
                                            flag2d = true;
                                        }
                                    }
                                    List<PartDescribeDocVO> partDescribeDocVOS1 = partDocMap.get(tyPartAllVO.getOid());
                                    for(PartDescribeDocVO partDescribeDocVO : partDescribeDocVOS1){
                                        BigInteger typeOid = partDescribeDocVO.getTypeoid();
                                        StdTypeDetailDTO stdTypeDetailDTO = typeData.get(typeOid);
                                        String inthid = stdTypeDetailDTO.getInthid();
                                        if(inthid.contains("设计图纸")){
                                            flagDoc = true;
                                        }
                                    }
                                    if(!flag2d || !flagDoc){
                                        errorMsg.append(tyPartAllVO.getMasterPartNumber()).append(
                                                "不存在对应的二维图纸或者设计图纸！");
                                    }
                                }
                            }
                        }
                    }
                    if(StringUtils.isNotBlank(errorMsg.toString())){
                        throw RTErrorCodeEnum.DEV_CODE_EXIST.getException(errorMsg.toString());
                    }
                }
            }
        }


}

